poj1723 SOLDIERS(思维题-中位数/货仓选址问题)

题目

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
#include
#include
#include
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

 

你可能感兴趣的:(思维题)