题意分析:
这道题是说:有n士兵分布在一个二维的平面上,现要求让这些站成平行于x轴的一排,即(x,y),(x+1,y),(x+2,y)....问如何移动这些士兵,使他们的移动步数最小。设他们没移动一下为一。我们分析可得,沿y轴移动,他们都统一移动到中位数的位置,上下移动的步数石最小的。因为沿x轴的位置是相邻的,我们可以设这些士兵当前在x轴上的位置分别为:x1,x2,x3....然后映射到x1 -> x, x2 -> x+1,x3 -> x+2...变形为x1 -> x, x2-1 -> x, x3-2 -> x....由此可以看成是求出x1, x2-1, x3-2。。。到他们中位数中间的距离的和。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct px {
int x,y;
}s[10010];
int cmp(struct px a,struct px b) {
return a.x < b.x;
}
int cmp1(struct px a1,struct px b1) {
return a1.y < b1.y;
}
int main() {
int n,i;
int sum=0;
cin>>n;
for(i=0; i<n; i++) cin>>s[i].x>>s[i].y;
sort(s,s+n,cmp1);
int index;
if(n%2) index = s[n/2].y;
else index =(s[n/2].y+s[n/2-1].y)/2;
for(i=0; i<n; i++) sum+=abs(s[i].y - index);
//cout<<sum<<endl;
sort(s,s+n,cmp);
for(i=0; i<n; i++) s[i].x-=i;
sort(s,s+n,cmp);
if(n%2) index = s[n/2].x;
else index =(s[n/2].x+s[n/2-1].x)/2;
//cout<<index<<endl;
for(i=0; i<n; i++) sum+=abs(s[i].x - index);
cout<<sum<<endl;
return 0;
}