1378: 士兵排阵Ⅱ

题目描述

在一个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));
发布了78 篇原创文章 · 获赞 7 · 访问量 4560

猜你喜欢

转载自blog.csdn.net/weixin_44433678/article/details/104845878