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
  • 相关阅读:
    eclipse下c/cpp " undefined reference to " or "launch failed binary not found"问题
    blockdev 设置文件预读大小
    宝宝语录
    CentOS修改主机名(hostname)
    subprocess报No such file or directory
    用ldap方式访问AD域的的错误解释
    英特尔的VTd技术是什么?
    This virtual machine requires the VMware keyboard support driver which is not installed
    Linux内核的文件预读详细详解
    UNP总结 Chapter 26~29 线程、IP选项、原始套接字、数据链路访问
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10040810.html
Copyright © 2011-2022 走看看