zoukankan      html  css  js  c++  java
  • [TJOI2013]松鼠聚会 曼哈顿距离

    [TJOI2013]松鼠聚会

    luogu P3964
    首先容易得到两点间距离是(max(|x_1-x_2|, |y_1-y_2|))(即切比雪夫距离)
    然后有个套路:原((x,y))求曼哈顿距离可以转换为((x+y,x-y))求切比雪夫距离,同样的((x,y))求切比雪夫距离就是求((frac{x+y}{2},frac{x-y}{2}))曼哈顿距离。
    然后考虑优化求(n-1)个总曼哈顿距离的过程
    先所有点以(x,y)分别作为关键字排序一遍,对于点(i)(sumx)可得

    [(x_i-x_1)+(x_i-x_2)+cdots+(x_i-x_i)+(x_{i+1}-x_i)+(x_{i+2}-x_i)+cdots +(x_n-x_i)\ i imes x_i-sum^i_{j=1} x_j+sum^n_{j=i+1} x_j-(n-i) imes x_i ]

    (sumy)同理
    不难发现我们维护一个前缀和即可。
    另外为了防止坐标出现小数所以我们就不除2了,在最后答案的时候再除2

    #include <cstdio>
    #include <climits>
    #include <algorithm>
    #define MAXN 100010
    #define ll long long
    using namespace std;
    int n;
    struct nod{
        int x,y;
    } a[MAXN];
    int sx[MAXN],sy[MAXN];
    ll sumx[MAXN],sumy[MAXN];
    int main(){
        scanf("%d", &n);
        for(int i=1;i<=n;++i){
            int xx,yy;
            scanf("%d %d", &xx, &yy);
            a[i].x=xx+yy;
            a[i].y=xx-yy;
            sx[i]=a[i].x;
            sy[i]=a[i].y;
        }
        sort(sx+1, sx+1+n);
        sort(sy+1, sy+1+n);
        for(int i=1;i<=n;++i) sumx[i]=sumx[i-1]+sx[i];
        for(int i=1;i<=n;++i) sumy[i]=sumy[i-1]+sy[i];
        ll ans=LLONG_MAX;
        for(int i=1;i<=n;++i){
            ll res=0;
            int k=lower_bound(sx+1, sx+1+n, a[i].x)-sx;
            res+=(ll)a[i].x*k-sumx[k]+sumx[n]-sumx[k]-(ll)(n-k)*a[i].x;
            k=lower_bound(sy+1, sy+1+n, a[i].y)-sy;
            res+=(ll)a[i].y*k-sumy[k]+sumy[n]-sumy[k]-(ll)(n-k)*a[i].y;
            ans=min(ans, res);
        }
        printf("%lld", ans/2);
        return 0;
    }
    
  • 相关阅读:
    九九乘法表
    计算器实现
    分装的日期类
    杨辉三角
    99乘法表
    素数
    java输出100以内质数
    跳台阶
    Counting Sheep
    课上作业
  • 原文地址:https://www.cnblogs.com/santiego/p/11677048.html
Copyright © 2011-2022 走看看