zoukankan      html  css  js  c++  java
  • HDU 5721Palace

    Palace

     
     Accepts: 28
     
     Submissions: 307
     Time Limit: 8000/4000 MS (Java/Others)
     
     Memory Limit: 262144/262144 K (Java/Others)
    问题描述
    为了寻找失去的爱人Cupid,Psyche需要完成Venus的最后一项任务:前往冥界,收集一盒冥界皇后Prosperina的美貌。
    
    冥界有nn个神殿,可以表示为平面上的nn个整点。Psyche想要找到这nn座神殿中,最近的两座神殿之间的距离。传说那就是通往主殿的密码。
    
    但是冥界神秘莫测,在不同的时刻,这nn座神殿中的某一座会消失。
    
    Psyche想要知道,对于nn座神殿中的任意一座消失的情况,最近的两座神殿之间的距离。你只需要输出它们的和。
    
    为避免精度误差,定义两点(x_1, y_1), (x_2, y_2)(x1,y1),(x2,y2)间的距离为d = (x_1 - x_2) ^ 2 + (y_1 - y_2) ^ 2d=(x1x2)2+(y1y2)2
    输入描述
    第一行,一个整数TT (1 le T le 5)(1T5),代表数据组数。
    
    对于每组数据,第一行,一个整数nn (3 le n le 10 ^ 5)(3n105),代表神殿个数。
    
    下面nn行,每行两个整数x, yx,y (-10 ^ 5 le x,y le 10 ^ 5)(105x,y105),代表神殿的位置在(x, y)(x,y)。
    
    注意可能存在两座神殿坐落在同一位置。
    输出描述
    输出TT行,对于每组数据,输出nn座神殿中的任意一座消失的情况,最近两座神殿之间的距离的和。
    输入样例
    1
    3
    0 0
    1 1
    2 2
    输出样例
    12
    Hint
    神殿(0,0)(0,0)消失时,d = (1-2) ^ 2 + (1 - 2) ^ 2 = 2d=(12)2+(12)2=2;
    
    神殿(1,1)(1,1)消失时,d = (0-2) ^ 2 + (0 - 2) ^ 2 = 8d=(02)2+(02)2=8;
    
    神殿(2,2)(2,2)消失时,d = (0-1) ^ 2 + (0-1) ^ 2 = 2d=(01)2+(01)2=2;
    
    故答案为2 + 8 + 2 = 122+8+2=12

    解题思路:

    感觉就是很裸的平面最近点对的模板题= =题解上的说的也很明确了,只有三种情况

    一种情况是删的点不属于最近点对里面的点

    剩下两种情况各删的最近点对里面的其中一点


    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define INF 1e18
    #define Min(a, b) ((a) <= (b) ? (a) : (b))
    
    typedef long long LL;
    typedef struct node{
        LL x, y;
        LL index;
    }Coord;
    
    const int maxn = 1e5 + 5;
    
    LL p1, p2, ans;
    Coord p[maxn], ppp[maxn], tmp[maxn];
    
    inline LL f(LL x){
        return (x >= 0 ? x : -x);
    }
    inline bool cmp(Coord a, Coord b){
        return a.x < b.x;
    }
    inline bool cmp2(Coord a, Coord b){
        return a.y < b.y;
    }
    inline LL Dist(Coord a, Coord b){
        return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
    }
    LL Cal_Closest(LL left, LL right, int step){
        LL d = INF;
        if(left == right){
            return d;
        }
        if(left + 1 == right){
            LL tmp2 = Dist(p[left], p[right]);
            if(step == 0){
                if(step == 0 && tmp2 < ans){
                    p1 = left;
                    p2 = right;
                    ans = tmp2;
                }
            }
            return tmp2;
        }
        
        LL mid = (left + right) >> 1;
        LL d1 = Cal_Closest(left, mid, step);
        LL d2 = Cal_Closest(mid + 1, right, step);
        d = Min(d1, d2);
        
        LL k = 0;
        for(LL i = left; i <= right; ++i){
            if(f(p[mid].x - p[i].x) <= d){
                tmp[k++] = p[i];
            }
        }
        sort(tmp, tmp + k, cmp2);
        
        for(LL i = 0; i < k; ++i){
            for(LL j = i + 1; j < k && tmp[j].y - tmp[i].y < d; ++j){
                if(d > Dist(tmp[i], tmp[j])){
                    d = Dist(tmp[i], tmp[j]);
                    if(step == 0 && d < ans){
                        p1 = tmp[i].index;
                        p2 = tmp[j].index;
                        ans = d;
                    }
                }
            }
        }
        return d;
    }
    
    int main()
    {
        LL t, n;
        scanf("%lld", &t);
        while(t--){
            scanf("%lld", &n);
            memset(p, 0, sizeof(p));
            memset(ppp, 0, sizeof(ppp));
            for(LL i = 0; i < n; ++i){
                scanf("%lld%lld", &p[i].x, &p[i].y);
            }
            
            sort(p, p + n, cmp);
            for(LL i = 0; i < n; ++i) p[i].index = i;
            for(LL i = 0; i < n; ++i) ppp[i] = p[i];
            p1 = 0; p2 = 0;
            ans = INF;
            
            ans = Cal_Closest(0, n - 1, 0);
            ans = ans * (n - 2);
            
            LL t = 0;
            for(LL i = 0; i < n; ++i){
                if(ppp[i].index == p1) continue;
                p[t++] = ppp[i];
            }
            sort(p, p + t, cmp);
            ans += Cal_Closest(0, t - 1, 1);
            
            t = 0;
            for(LL i = 0; i < n; ++i){
                if(ppp[i].index == p2) continue;
                p[t++] = ppp[i];
            }
            sort(p, p + t, cmp);
            ans += Cal_Closest(0, t - 1, 1);
            printf("%lld
    ", ans);
        }
        return 0;
    }


  • 相关阅读:
    Overloaded的方法是否可以改变返回值的类型
    parseXXX的用法
    java的类型转换问题。int a = 123456;short b = (short)a;System.out.println(b);为什么结果是-7616?
    UVA 10405 Longest Common Subsequence(简单DP)
    POJ 1001 Exponentiation(大数处理)
    POJ 2318 TOYS(计算几何)(二分)
    POJ 1265 Area (计算几何)(Pick定理)
    POJ 3371 Flesch Reading Ease (模拟题)
    POJ 3687 Labeling Balls(拓扑序列)
    POJ 1094 Sorting It All Out(拓扑序列)
  • 原文地址:https://www.cnblogs.com/wiklvrain/p/8179458.html
Copyright © 2011-2022 走看看