题目描述
在一个n*n的棋盘上,n个士兵散乱地站在网格上,网格由整数坐标(x,y)表示。士兵们可以在棋盘的网格上、下、左、右移动一步,但在同一时刻任一网格上只能有一名士兵。按照军官的命令,士兵们要整齐地排成一行或者一列。
请计算使所有士兵排成一行或者一列需要的最少移动步数。
输入
第一行一个正整数n,n<=5*10^5。
接下来n行,每行两个正整数x,y,表示该士兵在棋盘内的位置,其中x,y<=n。
输出
输出使所有士兵排成一行或者一列需要的最少移动步数。
样例输入
5
1 2
2 4
3 4
5 1
5 3
样例输出
6
思路:这题与士兵排阵1不同的地方在于这个棋盘是有边界的,排序完成时必然是士兵占满了从1到n的网格,这是若采用士兵1的方法,可能会溢出,如样例,如果输出答案为2,则代表发生了溢出,输出答案应为4,此时要求得最小值,应将士兵从头开始逐个放入指定的位置,这样既不会发生重叠现象,也不会溢出,具体实现看代码
4
1 2
1 1
2 1
3 1
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int A[N],B[N];
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&A[i],&B[i]);
}
sort(A,A+n);
sort(B,B+n);
long long ans1=0,ans2=0;
for(int i=0;i<n;i++){
ans1+=abs(A[i]-A[n/2]);
ans2+=abs(B[i]-B[n/2]);
}
for(int i=0;i<n;i++){
ans1+=abs(B[i]-i-1); ///将士兵逐个从头放入指定的位置
ans2+=abs(A[i]-i-1);
}
printf("%lld\n",min(ans1,ans2));