您的位置:首页 > 其它

hdu4311 Meeting point-1 求最小的曼哈顿距离和

2018-01-27 12:56 274 查看
曼哈顿距离:两个点在标准坐标系上的绝对轴距总和

可以表示为:


传送门

本题的题意:给定n个点,每个点到其他的点都可以取得曼哈顿距离和,求最小的距离和

思路:分别对x坐标、y坐标排序,我们可以先对x坐标排序,得到一个坐标序号,每个点的序号i的意义是:有i-1个点的横坐标比它小,有n-i个点的横坐标比它大,所以如果我们还可以求得一个x坐标的前缀和sumx的话,那么


就是比第i个点横坐标小的与第i个点横坐标差的和,即 

 ,

是比第i个点横坐标大的与第i个点横坐标差的和,即  


这两个相加就是 

,相应的对y也进行相同的操作,再找一次最小值就可以了

代码

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL N=0x7fffffffffffffff;
struct point
{
LL x,y;
LL idx,idy;
}p[100005];
bool cmp1(point p1,point p2)
{
return p1.x<p2.x;
}
bool cmp2(point p1,point p2)
{
return p1.y<p2.y;
}
LL sumx[100005],sumy[100005];
int main()
{
LL t;
scanf("%I64d",&t);
while(t--)
{
LL n;
scanf("%I64d",&n);
for(LL i=1;i<=n;i++)
scanf("%I64d%I64d",&p[i].x,&p[i].y);
sort(p+1,p+n+1,cmp1);
sumx[0]=0;
for(LL i=1;i<=n;i++)
{
p[i].idx=i;
sumx[i]=sumx[i-1]+p[i].x;
}
sort(p+1,p+n+1,cmp2);
sumy[0]=0;
for(LL i=1;i<=n;i++)
sumy[i]=sumy[i-1]+p[i].y;
LL ans=1LL<<62;
for(LL i=1;i<=n;i++)
{
LL sum=(i-1)*p[i].y-sumy[i-1]+(sumy
-sumy[i])-(n-i)*p[i].y;
sum=sum+(p[i].idx-1)*p[i].x-sumx[p[i].idx-1]+(sumx
-sumx[p[i].idx])-(n-p[i].idx)*p[i].x;
ans=min(ans,sum);
}
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: