标签:hdu
题意: 面上n个点,某点到其他点的曼哈顿距离最小和,切比雪夫距离最小和。
思路:对于切比雪夫距离可以转化为哈密顿距离,方法是将每个点的坐标逆时针旋转45度然后放大sqrt(2)倍,换成坐标表示也就是(x,y)->(x-y,x+y).
对于第一个问题,求曼哈顿距离最小和,也就是sum(xj-xi)+sum(yj-yi)。
如果直接求时间复杂度无法承受。
所以我们可以先对x排序,对于从左到右的sum(x)我们可以递推出来,即sumx[tj[i].id] = sumx[tj[i-1].id] + (2*i-n)*(tj[i].x-tj[i-1].x);
对于y同理。
附4312代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#define eps 1e-6
#define LL long long
#define pii pair<int,int>
using namespace std;
const int maxn = 100000 + 500;
//const int INF = 0x3f3f3f3f;
LL disx[maxn], disy[maxn];
LL sumv[maxn];
struct Point {
int x, y, id;
Point(int x=0, int y=0, int z=0) : x(x), y(y), id(z) {
}
} tj[maxn];
bool cmp1(Point A, Point B) {
return A.x < B.x;
}
bool cmp2(Point A, Point B) {
return A.y < B.y;
}
int main() {
// freopen("input.txt", "r", stdin);
int t; cin >> t;
while(t--) {
int n;
cin >> n;
for(int i = 0; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
tj[i] = Point(u-v, u+v, i);
}
sort(tj, tj+n, cmp1);
disx[tj[0].id] = 0;
for(int i = 1; i < n; i++) disx[tj[0].id] += (LL)tj[i].x - (LL)tj[0].x;
for(int i = 1; i < n; i++) disx[tj[i].id] = disx[tj[i-1].id] + (LL)(2*i-n)*(LL)(tj[i].x-tj[i-1].x);
sort(tj, tj+n, cmp2);
disy[tj[0].id] = 0;
for(int i = 1; i < n; i++) disy[tj[0].id] += (LL)tj[i].y - (LL)tj[0].y;
for(int i = 1; i < n; i++) disy[tj[i].id] = disy[tj[i-1].id] + (LL)(2*i-n)*(LL)(tj[i].y-tj[i-1].y);
LL ans = 100000000000000000;
for(int i = 0; i < n; i++) {
sumv[i] = disx[i] + disy[i];
// cout << disx[i] << " " << disy[i] << endl;
ans = min(ans, sumv[i]);
}
cout << ans/2 << endl;
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 4311,4312 Meeting point(曼哈顿距离,切比雪夫距离)
标签:hdu
原文地址:http://blog.csdn.net/u014664226/article/details/47173835