您的位置:首页 > 其它

nyoj--7 街区最短路径问题(枚举 or math)

2016-02-28 11:11 381 查看
nyoj 7

题解

暴力枚举。

#include <iostream>
#include <cstdio>
#include <fstream>
#include <cstring>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;

const int maxn = 20;
const int inf  = 1 << 30;
int   x[maxn], y[maxn], n;

int calc(int i, int j){
int sum = 0;
for(int k = 0; k < n; ++k)
{
sum += abs(i - x[k]) + abs(j - y[k]);
}
return sum;
}

int main()
{
//fstream cin("data.in");
int t;
for(cin >> t; t--; )
{
cin >> n;
for(int i = 0; i < n; ++i){
cin >> x[i] >> y[i];
}
int ans = inf;
for(int i = 0; i < 100; ++i)
{
for(int j = 0; j < 100; ++j)
{
int tmp = calc(i, j);
ans = min(ans, tmp);
}
}
cout << ans << endl;
}

return 0;
}


发现别人一种更优解法。

设邮局坐标(x,y),问题转化为求解 min(∑|xi−x|)+min(∑|yi−y|)

题目性质,这里x,y可分别求解,这式子可以表示为数轴上有n个点,求一点到其他各点的距离之和最小。

如果n为奇数,这点就是中间一点,否则是中间两点的中间点,两种情况下都有 最小和 = ∑n/2i=1(xn−i−xi) .

画下图不难理解。

#include <iostream>
#include <cstdio>
#include <fstream>
#include <cstring>
#include <set>
#include <cmath>
#include <algorithm>
using namespace std;

const int maxn = 20;
const int inf  = 1 << 30;
int   x[maxn], y[maxn], n;

int main()
{
//fstream cin("data.in");
int t;
for(cin >> t; t--; )
{
cin >> n;
for(int i = 0; i < n; ++i) cin >> x[i] >> y[i];

sort(x, x + n);
sort(y, y + n);
int ans = 0;
for(int i = 0; i < n / 2; ++i)
ans += x[n - 1 - i] - x[i] + y[n - 1 - i] - y[i];
cout << ans << endl;

}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  nyoj math easy