士兵站队问题
在一个划分成网格的操场上,n个士兵散乱地站在网格点上。网格点由整数坐标(x,y)表示。士兵们可
以沿网格边上、下、左、右移动一步,但在同一时刻任一网格点上只能有一名士兵。按照军官的命令,士
兵们要整齐地列成一个水平队列,即排列成(x,y),(x+1,y),…,(x+n-1,y)。如何选择x 和y的值才能使士兵们以最少的总移动步数排成一列。
【编程任务】
计算使所有士兵排成一行需要的最少移动步数。
输入描述:
计算使所有士兵排成一行需要的最少移动步数。
输出描述:
第1 行是士兵数n,1≤n≤10000。接下来n 行是士兵的初始位置,每行2 个整数x 和y,-10000≤x,
y≤10000。
示例1
输入
5
1 2
2 2
1 3
3 -2
3 3
输出
8
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
bool cmp(int x,int y)
{
return x<y;
}
ll a[200020]={0},b[200020];
//这个题就需要对x进行存储,进行计算了
//对于y来说还是和之前一样的操作
//对于x来说需要改变一下
//假设第一个数排在k+1处,后面的依次类推
//那么需要进行的变化就是(a[0]-(k+1)) (a[1]-(k+2)) ....
//那么对它进行变化— —变成((a[0]-1)-k) ...
//那么对于每一个a[i]都是先减去了一个i+1,再减去了一个k
//这个时候可以想到对y进行的操作不就是共同减去了一个y轴上的数值的中位数吗
//所以先对x进行一次排序,然后减去一个i+1
//再次排序,和y进行相同的操作
int main()
{
int n,i,j,k;
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i]>>b[i];
}
sort(a,a+n,cmp);
sort(b,b+n,cmp);
for(i=0;i<n;i++)
{
a[i]=a[i]-i;
}
sort(a,a+n,cmp);
int sum=0;
for(i=0;i<n;i++)
{
sum+=fabs(a[i]-a[n/2]);
sum+=fabs(b[i]-b[n/2]);
//cout<<sum<<endl;
}
cout<<sum;
return 0;
}