bzoj3170 [Tjoi 2013]松鼠聚会
2016-05-21 21:04
239 查看
Description
有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1。现在N个松鼠要走到一个松鼠家去,求走过的最短距离。Input
第一行给出数字N,表示有多少只小松鼠。0<=N<=10^5 下面N行,每行给出x,y表示其家的坐标。 -10^9<=x,y<=10^9Output
表示为了聚会走的路程和最小为多少。首先等价变换,旋转坐标系45度,将点(x,y)改为((x+y)/2,(x-y)/2),原距离定义改为曼哈顿距离
枚举每个点,分别计算其余点与其x,y坐标差之和
#include<cstdio> #include<algorithm> char buf[10000005],*ptr=buf-1; inline int input(){ int x=0,c=*++ptr,f=1; while(c>57||c<48){if(c=='-')f=-1;c=*++ptr;} while(c>47&&c<58)x=x*10+c-48,c=*++ptr; return x*f; } const int N=100500; int n; int x0 ,y0 ,xv ,yv ; long long xs ,ys ,ans=1ll<<62; int main(){ fread(buf,1,10000000,stdin); n=input(); for(int i=1;i<=n;i++){ int x=input(),y=input(); x0[i]=xv[i]=x+y; y0[i]=yv[i]=x-y; } std::sort(xv+1,xv+n+1); std::sort(yv+1,yv+n+1); for(int i=1;i<=n;i++){ xs[i]=xs[i-1]+xv[i]; ys[i]=ys[i-1]+yv[i]; } for(int i=1;i<=n;i++){ int m=std::lower_bound(xv+1,xv+n+1,x0[i])-xv; long long s=(1ll*x0[i]*m-xs[m])+(xs -xs[m]-1ll*x0[i]*(n-m)); m=std::lower_bound(yv+1,yv+n+1,y0[i])-yv; s+=(1ll*y0[i]*m-ys[m])+(ys -ys[m]-1ll*y0[i]*(n-m)); if(s<ans)ans=s; } printf("%lld\n",ans>>1); return 0; }
相关文章推荐
- 重建二叉树
- 学会自己测天气-----04
- 深入理解JVM07--虚拟机类加载机制--类加载过程
- flume学习(四):Flume Channel Selectors使用
- ### 我的网址收藏 ###
- 2.html5的基本格式
- C++primer_第五章_语句_学习跟踪
- 【EF】DbFirst实现增删改查
- Django笔记 no such table: django_session错误
- C++之命名空间
- hdu 5690 All X
- flume学习(三):Flume Interceptors的使用
- android点击菜单子项无响应的解决办法listView
- Nginx配置proxy_pass转发的/路径问题
- C++静态库基本编程
- 第10.11补充-2
- flume学习(二):如何找到cm安装的flume的配置文件
- HDU 5543 Pick The Sticks 背包变形 ccpc
- POJ 3711 Scout YYF I 概率DP + 矩阵快速幂
- C++primer_第四章_表达式_学习跟踪