Description
总所周知,韩信是一位神勇的军事家。某日夜幕,敌方突然来袭,韩信作为塞外将帅吹响紧急的号角。各个帐内的士兵听见号角立即集合,站成一排,排成连续的一队。但是士兵太多了,如果让他们集合耗费太多精力就没有办法打好接下来的胜仗,因此韩信希望选择一个最优的方案使得所有士兵从帐内移动到将要站队的位置的曼哈顿距离和最小!
解题思路:
题要求所有人站到一列,而x与y可以独立考虑。先考虑简单的y坐标,不妨设在y点时走的步数最少,则Sy=|Y0-y|+|Y1-y|+|Y2-y+ ……+|Yn-1-y|根据绝对值的性质我们得y取在Y0~Yn-1这些数的中位数时Sy最小
再看x坐标,不妨设第一个人站在x时总步数最少,则剩下人根据Xi的大小依次往后站,不可能存在Xi<Xj但i站在j后面的情况,否则交换得到更优解。
因此先对x排序,
计算Sx=|X0-x|+|X1- (x+1) |+|X2-(x+2)|+ …… +|Xn-1-(x+(n-1))|
经过变形Sx=|X0-x|+|(X1-1)-x|+|(X2-2)-x|+ …… …… +|(Xn-1-(n-1))-x|
故同理对Xi-i进行排序,取中位数的最小值。
再进行遍历将所需步数加上
代码:
#include<iostream>
#include<algorithm>
using namespace std;
int x[100010];
int y[100010];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>x[i];
cin>>y[i];
}
sort(x,x+n);
for(int i=0;i<n;i++)x[i]-=i;
sort(x,x+n);
sort(y,y+n);
long long ans=0;
for(int i=0;i<n;i++){
ans+=abs(x[i]-x[n/2]);
ans+=abs(y[i]-y[n/2]);
}
cout<<ans<<endl;
}