题目
n(n<=1e4)个士兵,第i个士兵的位置(xi,yi),-1e4<=xi,yi<=1e4
把士兵安排到同一条水平线上,使之在竖直方向n个士兵相邻
最后排成(x,y),(x+1,y),...(x+n-1,y)的样子,移动的代价是曼哈顿距离
最小化移动代价和,输出这个和
思路来源
https://blog.csdn.net/flora715/article/details/81017961
题解
和东北赛三分写的题,和之前做过的abc的中位数/三分的题,都很像
货仓选址问题,一维上选择一个位置使得所有位置到此处和最小,此处可以用中位数搞
注意到二维是可以抽象成两个独立的一维问题的,互不影响
//以下思路,来自思路来源网址,代码部分
x方向:对所有x坐标从小到大排序,由于要移动步数最少,
所以【最终的x坐标相对位置】与【排序后的x坐标相对位置】相同。
设最终的x坐标起始位置为a,则:
x[0] -> a (->表示移动)
x[1] -> a+1
....
x[n-1] -> a+n-1
即 x[0] -> a
x[1]-1 -> a
x[2]-2 -> a
....
x[n-1]-n-1 ->a ... 将所有x[i]-i移动到相同位置。
于是重新计算x[i]=x[i]-i,然后重新进行排序。
移动步数最少,类似蚂蚁相遇的入门题,交叉认为是不交叉的挪动,所以相对位置不变
设出最后的位置后再求解,这题主要考察的思维,就是这里吧
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e4+10;
int n,x[maxn],y[maxn];
int ans,mid;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d%d",&x[i],&y[i]);
sort(x+1,x+n+1);
for(int i=1;i<=n;++i)
x[i]=x[i]-i+1;
sort(x+1,x+n+1);
sort(y+1,y+n+1);
mid=(n+1)/2;
for(int i=1;i<mid;++i)
ans+=x[mid]-x[i],ans+=y[mid]-y[i];
for(int i=mid+1;i<=n;++i)
ans+=x[i]-x[mid],ans+=y[i]-y[mid];
printf("%d\n",ans);
return 0;
}