zoukankan      html  css  js  c++  java
  • [TJOI2013]松鼠聚会 BZOJ 3170

    题目描述

    草原上住着一群小松鼠,每个小松鼠都有一个家。时间长了,大家觉得应该聚一聚。但是草原非常大,松鼠们都很头疼应该在谁家聚会才最合理。

    每个小松鼠的家可以用一个点x,y表示,两个点的距离定义为点(x,y)和它周围的8个点(x-1,y)(x+1,y),(x,y-1),(x,y+1).(x-1,y+1),(x-1,y-1),(x+1,y+1),(x+1,y-1)距离为1。

    输入输出格式

    输入格式:

    第一行是一个整数N,表示有多少只松鼠。接下来N行,第i行是两个整数x和y,表示松鼠i的家的坐标

    输出格式:

    一个整数,表示松鼠为了聚会走的路程和最小是多少。

    输入输出样例

    输入样例#1: 复制
    6
    -4 -1
    -1 -2
    2 -4
    0 2
    0 3
    5 -2
    输出样例#1: 复制
    20
    输入样例#2: 复制
    6
    0 0
    2 0
    -5 -2
    2 -2
    -1 2
    4 0
    输出样例#2: 复制
    15

    说明

    样例解释

    在第一个样例中,松鼠在第二只松鼠家(-1,-2)聚会;在第二个样例中,松鼠在第一只松鼠家(0.0)聚会。

    数据范围

    30%的数据,0 ≤ N ≤ 1000

    100%的数据,0 ≤ N ≤ 100000; −10^9 ≤ x, y ≤ 10^9

    首先我们要求的是 切比雪夫距离。

    也就是 dis=max( |dx|,|dy|);

    看样子可能不太好求解;

    想办法转换为 曼哈顿距离;

    在(x,y)坐标系中进行变换----> ( (x+y)/2,(x-y)/2 );

    可以发现原坐标系中的 切比雪夫距离 就是新坐标系中的 曼哈顿距离 ;

    (推一下即可);

    那么我们考虑用 曼哈顿距离求解:

    Mdis(i,k) 即该值最小;

    将其变为有序方便处理(不妨设为升序);

    即 Mdis(1,i)+Mdis(2,i)+...+Mdis(n,i)

    现以X坐标为例:

    即 x[ i ]-x[ 1 ]+x[ i ]-x[ 2 ]+...+x[ i+1 ]-x[ i ]+...x[ n ]-x[ i ]

    = i*x[ i ]- sum[ i ]+sum[ n ]-sum[ i ]+(n-i)*x[ i ];

    那么就可以用前缀和进行维护了;

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<ctime>
    #include<deque>
    #include<stack>
    #include<functional>
    #include<sstream>
    
    //#include<cctype>
    //#pragma GCC optimize("O3")
    using namespace std;
    #define maxn 300005
    #define inf 0x3f3f3f3f
    #define INF 9999999999
    #define rdint(x) scanf("%d",&x)
    #define rdllt(x) scanf("%lld",&x)
    #define rdult(x) scanf("%lu",&x)
    #define rdlf(x) scanf("%lf",&x)
    #define rdstr(x) scanf("%s",x)
    typedef long long  ll;
    typedef unsigned long long ull;
    typedef unsigned int U;
    #define ms(x) memset((x),0,sizeof(x))
    const long long int mod = 1e9 + 7;
    #define Mod 1000000000
    #define sq(x) (x)*(x)
    #define eps 1e-3
    typedef pair<int, int> pii;
    #define pi acos(-1.0)
    //const int N = 1005;
    #define REP(i,n) for(int i=0;i<(n);i++)
    
    inline ll rd() {
        ll x = 0;
        char c = getchar();
        bool f = false;
        while (!isdigit(c)) {
            if (c == '-') f = true;
            c = getchar();
        }
        while (isdigit(c)) {
            x = (x << 1) + (x << 3) + (c ^ 48);
            c = getchar();
        }
        return f ? -x : x;
    }
    
    ll gcd(ll a, ll b) {
        return b == 0 ? a : gcd(b, a%b);
    }
    ll sqr(ll x) { return x * x; }
    
    /*ll ans;
    ll exgcd(ll a, ll b, ll &x, ll &y) {
        if (!b) {
            x = 1; y = 0; return a;
        }
        ans = exgcd(b, a%b, x, y);
        ll t = x; x = y; y = t - a / b * y;
        return ans;
    }
    */
    
    
    
    ll qpow(ll a, ll b, ll c) {
        ll ans = 1;
        a = a % c;
        while (b) {
            if (b % 2)ans = ans * a%c;
            b /= 2; a = a * a%c;
        }
        return ans;
    }
    
    int n;
    int x[maxn], y[maxn];
    ll ans, tmp, sumx[maxn], sumy[maxn];
    struct node {
        ll x, y;
    }a[maxn];
    
    int main()
    {
        //ios::sync_with_stdio(0);
        rdint(n);
        for (int i = 1; i <= n; i++) {
            int xx, yy;
            rdint(xx); rdint(yy);
            x[i] = a[i].x = xx + yy; y[i] = a[i].y = xx - yy;
        }
        sort(x + 1, x + 1 + n); sort(y + 1, y + 1 + n);
        for (int i = 1; i <= n; i++)
            sumx[i] = sumx[i - 1] + x[i], sumy[i] = sumy[i - 1] + y[i];
        ans = 100000000000000000;
        for (int i = 1; i <= n; i++) {
            int pos = lower_bound(x + 1, x + 1 + n, a[i].x) - x;
            tmp = sumx[n] - sumx[pos] - a[i].x*(n - pos) + pos * a[i].x - sumx[pos];
            pos = lower_bound(y + 1, y + 1 + n, a[i].y) - y;
            tmp += sumy[n] - sumy[pos] - a[i].y*(n - pos) + a[i].y*pos - sumy[pos];
            ans = min(ans, tmp);
        }
        cout << ans / 2 << endl;
        return 0;
    }
    
    EPFL - Fighting
  • 相关阅读:
    C语言 · 9-1九宫格
    Lodop打印控件指定打印任务某几页
    Lodop打印控件不打印css背景图怎么办
    Lodop打印项对象类型属性区分
    Lodop打印如何隐藏table某一列
    Lodop打印控件 打印‘接下一页’‘以下空白’
    Lodop连续打印内容逐渐偏移怎么办
    C-Lodop打印服务没启动怎么办
    LODOP.FORMAT格式转换【回调和直接返回值】
    C-Lodop设置页面一加载就打印
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10040810.html
Copyright © 2011-2022 走看看