http://acm.hdu.edu.cn/showproblem.php?pid=4311
题意:
在二维坐标中有n个点,现在要从这n个点中选出一个点,使得其他点到该点的曼哈顿距离总和最小。
思路:
离散化分别处理x坐标和y坐标。
将点按照x坐标进行排序,sum数组记录记录前缀和,那么当选第i个点时其余点在x轴到该点的距离为 $(i-1)*p[i].x-sumx[i-1] + (sumx[n]-sumx[i]) - (n-i)*p[i].x$。
y坐标同理。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 typedef long long ll; 6 7 int n; 8 9 struct node 10 { 11 ll x,y; 12 int id; 13 }p[100005]; 14 15 ll sumx[100005],sumy[100005]; 16 ll numx[100005],numy[100005]; 17 18 bool cmp1(node a, node b) 19 { 20 return a.x < b.x; 21 } 22 23 bool cmp2(node a, node b) 24 { 25 return a.y < b.y; 26 } 27 28 int main() 29 { 30 int T; 31 scanf("%d",&T); 32 while(T--) 33 { 34 scanf("%d",&n); 35 for(int i=1;i<=n;i++) 36 { 37 scanf("%lld%lld",&p[i].x,&p[i].y); 38 p[i].id = i; 39 } 40 41 sumx[0] = sumy[0] = 0; 42 sort(p+1,p+n+1,cmp1); 43 for(int i=1;i<=n;i++) sumx[i] = sumx[i-1] + p[i].x; 44 for(int i=1;i<=n;i++) numx[p[i].id] = ((i-1)*p[i].x-sumx[i-1] + (sumx[n]-sumx[i]) - (n-i)*p[i].x); 45 sort(p+1,p+n+1,cmp2); 46 for(int i=1;i<=n;i++) sumy[i] = sumy[i-1] + p[i].y; 47 for(int i=1;i<=n;i++) numy[p[i].id] = ((i-1)*p[i].y-sumy[i-1] + (sumy[n]-sumy[i]) - (n-i)*p[i].y); 48 49 ll ans = numx[1] + numy[1]; 50 for(int i=2;i<=n;i++) 51 ans=min(ans,numx[i]+numy[i]); 52 printf("%lld ",ans); 53 } 54 return 0; 55 }