1490. 士兵

题目描述

在Gridland国家,有N个处于不同位置的士兵。该国上的地方都用两个坐标(X,Y)来表示。士兵能进行一次移动,每个士兵都可向上、向下、向左、或向右移动一个单位长,这样他就能把自己的X或Y改变1或-1。
士兵们想进入一个水平线,彼此靠近,这样他们的最后位置就是(X,Y)、(X+1,Y),…,(X+N,Y))。水平线上的士兵的最后顺序以及整数X和Y,都是任意的。

现在目标是求如此配置士兵的最少移动数。

两个或两个以上的士兵在同一时间不处于同一位置。

输入

输入文件soldiers.in的第一行含有一个整数N,1 <= N <=10000,N为士兵的数量。输入文件以后的N行应含有士兵的初始位置,对于每一个i, 1<= i <= N,输入文件的第I+1行含有两个用空格分开的整数x[i],y[i],他们表示第I个士兵的坐标,-10000<=x[i],y[i] <=10000.

输出

输出文件soldiers.out仅有一行,它的值为使士兵移动到水平线彼此相邻的最小移动次数。

Code

# include<cstdio>
# include<cmath>
# include<algorithm>
# include<cctype>
using namespace std;
const int maxn = 1e4;
int x[maxn + 10],y[maxn + 10];
inline int read()
{
    int ret = 0,w = 0; 
    char ch = 0;
    while(!isdigit(ch)) 
    {
        w |= ch == '-';
        ch = getchar();
    }
    while(isdigit(ch)) 
    {
        ret = (ret << 3) + (ret << 1) + (ch ^ 48);
        ch = getchar();
    }
    return w ? -ret : ret;
}
inline void write(int x)
{
     if(x < 0) 
        putchar('-'),x = -x;
     if(x > 9) 
        write(x / 10);
     putchar(x % 10 + '0');
}
int main()
{
    freopen("soldiers.in","r",stdin);
    freopen("soldiers.out","w",stdout);
    int n,i,k,ans;
    n = read();
    for(i = 1;i <= n;i++)
    {
        x[i] = read();
        y[i] = read();
    }
    sort(x + 1,x + n + 1);
    sort(y + 1,y + n + 1);
    for(i = 1;i <= n;i++)
        x[i] -= i;
    sort(x + 1,x + n + 1);
    ans = 0,k = (n + 1) / 2;
    for(i = 1;i <= n;i++)
        ans += abs(x[i] - x[k]) + abs(y[i] - y[k]);
    write(ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40155097/article/details/95304339
今日推荐