• TOJ 3589 likaer的最长点距


    传送门:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=3589

    时间限制(普通/Jav a):7000MS/70000MS     内存限制:65536KByte

    描述

    我们都知道,炉子喜欢做题,尤其喜欢做likaer等牛出的神题。比如昨天炉子经过一天的奋斗,终于找到一个O(N ^ 2)的算法,成功水过了likaer牛出的最长点距(http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=3580)。
    likaer牛深感压力很大――“这样的题都需要花一天……”,于是就给把N改成了50000,“接着做吧孩子。”
    我们都知道炉子喜欢问问题――因为他什么都不会。所以炉子找到了你,一个强大的ACMer,来帮他解决这个问题。

    输入

    输入的第一行是样例数T,1 ≤ T ≤ 50。
    每组样例第一行有一个整数N,是点的个数,1 ≤ N ≤ 50,000;
    接下来有N行,每行两个整数Xi、Yi,是第i个点的X、Y坐标,-10,000 ≤ Xi ≤ 10,000,-10,000 ≤ Yi ≤ 10,000。

    输出

    每组样例输出一行,包含一个整数X,是最远的两个点的距离的平方(请注意不是距离而是距离的平方――这样可以避免使用double。)。

    样例输入

    1
    3
    0 0
    1 1
    2 2

    样例输出

     8

    思路:因为n特别大,所以不能用暴力两个for循环遍历所有点找最远两个点。

             考虑到最远点肯定在凸包上,所以转化为在先求凸包,再在凸包上循环2次暴力找最远点,这样就不会超时了

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<queue>
    #include<set>
    #include <sstream>
    #include <assert.h>
    #define LL long long
    using namespace std;
    int i,j,k,n,top,ans;
    struct note{
        int x,y;
    }p[50010],stack[50010];
    int dis(note a,note b){
        return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
    }
    int mult(note p1,note p2,note p0){
        return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
    }
    int cmp(note a,note b){
        if(mult(a,b,p[0]) > 0){
            return 1;
        }
        else if(mult(a,b,p[0]) == 0 && (dis(a,p[0]) < dis(b,p[0]))){
            return 1;
        }
        return 0;
    }
    void solve(){
        k = 0;
        for(i = 1 ; i < n ; i++){
            if(p[k].y > p[i].y || (p[k].y == p[i].y) && p[k].x > p[i].x)
                k = i;
        }
        swap(p[0],p[k]);
        sort(p+1,p+n,cmp);
        top = 2;
        stack[0] = p[0];
        stack[1] = p[1];
        stack[2] = p[2];
        for(i = 3 ;i < n ; i++){
            while(top > 1 &&mult(p[i],stack[top],stack[top - 1]) >= 0)top--;
            stack[++top] = p[i];
        }
    }
    int main(){
        int t;
        for(scanf("%d",&t);t--;){
            scanf("%d",&n);
            for(i = 0 ; i < n ; i++){
                scanf("%d %d",&p[i].x,&p[i].y);
            }
            solve();
            ans = -1000;
            for(i = 0 ; i <= top ; i++){
                for(j = i+1 ;j <= top ; j++){
                    if(ans < dis(stack[i],stack[j])){
                        ans = dis(stack[i],stack[j]);
                    }
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    isequal 和startswith 使用
    UVa10340
    UVa1368
    UVa455
    UVa1225
    UVa1586
    UVa 1585
    UVa10082
    UVa272
    NYOJ1
  • 原文地址:https://www.cnblogs.com/Esquecer/p/8438781.html
Copyright © 2020-2023  润新知