您的位置:首页 > 其它

hdu - 4312 - Meeting point-2 - 数学 + 想法

2012-10-16 13:07 405 查看

题意, 一个方格到相邻八个点的距离都为1.

http://acm.hdu.edu.cn/showproblem.php?pid=4312

给你好多个点的坐标,让你求一个点满足到其他点的距离最短。

解:

其实也是暴力枚举,貌似没有比他更好的方法。 但是枚举的时候做些预处理就行,参见4311.

其他就需要了解的就是chebyshev距离和manhattan距离的转化了。

我照着题解静下心来认真看了,终于觉得题解是对的了。

平面上两点间的 Chebyshev距离为 max(|x1-x2|, |y1-y2|)





Chebyshev Manhattan

对于原坐标系中两点间的 Chebyshev 距离,是将坐标轴顺时针旋转45度并将所有点的坐标值放大sqrt(2)倍所得到的新坐标系中的Manhattan距离的二分之一。

大家可以画图想一下……

假设有两点(x1,y1), (x2,y2),不妨设 x1>x2(否则交换这两点即可)。

则Chebyshev距离 D1 = max(|x1-x2|, |y1-y2|)

这两点个对应到新坐标系中的坐标为 (x1-y1, x1+y1), (x2-y2, x2+y2)

则Manhattan 距离D2 = |x1-y1-x2+y2| + |x1+y1-x2-y2|

分四种情况讨论:

1.1 y1>y2 && x1-x2>y1-y2

D1 = max(x1-x2, y1-y2) = x1 - x2

D2 = x1-y1-x2+y2 + x1+y1-x2-y2 = 2(x1-x2)

1.2 y1>y2 && x1-x2<=y1-y2

D1 = max(x1-x2,y1-y2) = y1-y2

D2 = -(x1-y1-x2+y2) + x1+y1-x2-y2 = 2(y1-y2)

2.1 y1<=y2 && x1-x2>y2-y1

D1 = max(x1-x2, y2-y1) = x1-x2

D2 = x1-y1-x2+y2 + x1+y1-x2-y2 = 2(x1-x2)

2.2 y1<=y2 && x1-x2<=y2-y1

D1 = max(x1-x2, y2-y1) = y2-y1

D2 = x1-y1-x2+y2 - (x1+y1-x2-y2) = 2(y2-y1)

所以先将Chebyshev距离形式转化成Manhattan距离的形式再求解,求解过程参考 Meeting point-2

将4311代码改了三行,就过了。。。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define maxn 100010
typedef long long L;
using namespace std;

struct Node{
long long x,y;
int id;
} p[maxn];
long long sumx[maxn],sumy[maxn];
bool cmpx(Node a , Node b){
return a.x < b.x;
}
bool cmpy(Node a, Node b){
return a.y < b.y;
}
int T, n;
long long tmpx, tmpy;//改的地方
int main(){
scanf("%d",&T);
while(T --){
scanf("%d",&n);
for(int i = 1; i <= n; ++ i){
scanf("%I64d%I64d", &tmpx, &tmpy);
p[i].x = tmpx - tmpy;//改的地方
p[i].y = tmpx + tmpy;//改的地方
}
sort(p + 1, p + 1 + n, cmpx);
sumx[1] = p[1].x;p[1].id = 1;

for(int i = 2; i <= n; ++ i){
sumx[i] = sumx[i - 1] + p[i].x;
p[i].id = i;
}

sort(p + 1, p + 1 + n, cmpy);
sumy[1] = p[1].y;
for(int i = 2; i <= n; ++ i){
sumy[i] = sumy[i - 1] + p[i].y;
}

long long ans = (1LL << 60);//
for(int i = 1; i <= n; i ++){
int j = p[i].id;

long long yy = ( p[i].y ) * (i * 1.0) - sumy[i];
yy += (sumy
- sumy[i] - (p[i].y) * ((n - i) * 1.0) );

long long xx = ( p[i].x ) * (j * 1.0) - sumx[j];
xx += (sumx
- sumx[j] - (p[i].x) * ((n - j) * 1.0) );
xx += yy;

ans = min(xx,ans);
}
printf("%I64d\n", ans / 2);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: