zoukankan      html  css  js  c++  java
  • 【POJ1723】SOLDIERS(中位数,货仓选址)

    problem

    • 平面上有N(N<=10000)个点
    • 求这些点变成一条水平线的最小移动步数

    solution

    • 对于y轴,易证得在中位数处取到最优,直接排序统计即可。
    • 对于x轴,因为要保证相对顺序,(比如:原来三个士兵的x坐标是 -1 5 6,那么在他们移动之后,假设移动成一条直线之后,起点是原来-1的那个士兵,现在的坐标是9,那么他们之间的相对位置就是9 10 11…)
      1、假设最后水平线的起点是a,根据上面的理论可以得到 x’[0] = a, x’[1] = a+1, x’[2] = a+2…
      2、移项,可以得到x[0] - 0 = a, x[1] - 1 = a, x[2] - 2 = a…..
      3、所以我们把每个x[i] 都减去i,然后再从小到大排序,这样就保证在相对位置不变的情况下成一条水平线。然后把距离差求和就可以了。

    codes

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int a[10010], b[10010];
    int main(){
        int n;  cin>>n;
        for(int i = 1; i <= n; i++)
            cin>>a[i]>>b[i];
        sort(b+1,b+n+1);
        int y = b[n+1>>1];
        sort(a+1,a+n+1);
        for(int i = 1; i <= n; i++)a[i]-=i;
        sort(a+1,a+n+1);
        int x = a[n+1>>1];
        int ans = 0;
        for(int i = 1; i <= n; i++)
            ans += abs(a[i]-x)+abs(b[i]-y);
        cout<<ans<<'
    ';
        return 0;
    }
  • 相关阅读:
    字符串
    完全背包
    背包2
    0-1背包
    生日劲歌会
    设计照明系统
    宝岛探险
    汉诺塔问题
    并查集 黑帮危机
    数塔问题
  • 原文地址:https://www.cnblogs.com/gwj1314/p/9444767.html
Copyright © 2011-2022 走看看