zoukankan      html  css  js  c++  java
  • POJ2187旋转卡壳

    // POJ 2187 Beauty Contest -- Andrew凸包算法 + 点对距离最长(旋转卡壳)
    // 大意:给你一堆点,让你求出相隔最远的两点距离并输出
    // 要求:最后结果不需要开平方 应为距离的平方
    //
    /*test data
    5
    1 3
    2 1
    4 1
    5 3
    3 5
        == 17
    
    */
    
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    
    const double Pzero = 0.000001;
    const int MAXP = 50005;
    
    struct Point
    {
        double x, y;//点对应坐标
        Point() {}
        Point(double x, double y):x(x), y(y) {}//使用两点进行初始化
    } p[MAXP],CHp[MAXP*2];
    typedef Point Vec;
    template<class T> inline T sqr(T x)//求平方 
    {
        return x * x;
    }
    Vec operator - (Vec a, Vec b)//点减法 
    {
        return Vec(a.x - b.x, a.y - b.y);
    }
    bool operator < (Point a, Point b)//平面直角坐标系中左下方的为小 
    {
        return a.x < b.x || (a.x == b.x && a.y < b.y);
    }
    inline double crossDet(Vec a, Vec b)//叉乘 
    {
        return a.x * b.y - a.y * b.x;
    }
    inline double crossDet(Point o, Point a, Point b)//向量叉乘 
    {
        return crossDet(a - o, b - o);
    }
    int andrew(Point *pt, int n, Point *ch)
    {
        sort(pt, pt + n);
        int m = 0;
        for(int i = 0; i < n; i++)
        {
            while(m > 1 && crossDet(ch[m - 1] - ch[m - 2], pt[i] - ch[m - 2]) <= 0) m--;
            ch[m++] = pt[i];
        }
        int k = m;
        for(int i = n - 2; i >= 0; i--)
        {
            while(m > k && crossDet(ch[m - 1] - ch[m - 2], pt[i] - ch[m - 2]) <= 0) m--;
            ch[m++] = pt[i];
        }
        if(n > 1) m--;
        return m;
    }
    inline double unsqrtptDis(Point a, Point b)//内敛点间距 
    {
        return sqr(a.x - b.x) + sqr(a.y - b.y);
    }
    double rotating_calipers(Point *ch, int n){// 旋转卡壳 求点对最长距离     效率 O(n)
        // ch[] 凸包 为逆时针给出的
        // 计算最长距离的时候,枚举了每一条边 |p p+1| 及 离该边最远的点q 的情况, 每一次计算点到边两端的距离,并更新一下ans(取最大值)
        // 如果遇到下一个点与该线段围成的三角形面积(即叉积) 比这一次变大了,则比较下一个点 (即q++)
        // 如果遇到下一个点与该线段围成的三角形面积(即叉积) 比这一次变小了,则计算两个距离(因为会出现平行的情况)并更新ans
        // POJ 2187 暴力可过 肯定凸包的顶点数不多
    
        int q = 1;double ans = 0;
        ch[n] = ch[0]; // ch[q+1] 可能会访问到
        for(int p = 0; p <n; p++){
            // 此处遍历的线段为 |p->p+1| 点为 q 
            // 所以叉积的意义为 线段|p->p+1| 和 点q 围成的三角形的有向面积,逆时针为正,因此在这里均为正
            while(crossDet(ch[p+1], ch[q], ch[p]) < crossDet(ch[p+1], ch[q+1], ch[p]))
                q = (q + 1) % n; // 移到下一个点,因为q可能会转几圈,因此对n取余
    
            // 这里要比较q点到线段 |p->p+1| 两个端点的距离,因为有可能在旋转的时候两个边平行
            ans = max( ans, max(unsqrtptDis(ch[p], ch[q]), unsqrtptDis(ch[p+1], ch[q+1])) );            
        }
        return ans; 
    }
    
    void InitInput(int n){
        for(int i=0;i<n;i++){
            scanf("%lf%lf", &p[i].x, &p[i].y);
        }
    }
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
    //    freopen("C:\Users\Sky\Desktop\1.in","r",stdin);
        int n;
        while( ~scanf("%d",&n) ){
            InitInput(n);
            int nCHp = andrew(p,n,CHp); // 返回凸包的顶点数
            //reverse(&CHp[0],&CHp[nCHp+1]);
            // for(int i=0;i<=nCHp;i++)
            // {
            //     printf("%.0lf %.0lf
    ",CHp[i].x,CHp[i].y);
            // }
            printf("%.0lf
    ", rotating_calipers(CHp, nCHp) );
        }
        return 0;
    }
    View Code
    Beauty Contest
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 25095   Accepted: 7702

    Description

    Bessie, Farmer John's prize cow, has just won first place in a bovine beauty contest, earning the title 'Miss Cow World'. As a result, Bessie will make a tour of N (2 <= N <= 50,000) farms around the world in order to spread goodwill between farmers and their cows. For simplicity, the world will be represented as a two-dimensional plane, where each farm is located at a pair of integer coordinates (x,y), each having a value in the range -10,000 ... 10,000. No two farms share the same pair of coordinates.

    Even though Bessie travels directly in a straight line between pairs of farms, the distance between some farms can be quite large, so she wants to bring a suitcase full of hay with her so she has enough food to eat on each leg of her journey. Since Bessie refills her suitcase at every farm she visits, she wants to determine the maximum possible distance she might need to travel so she knows the size of suitcase she must bring.Help Bessie by computing the maximum distance among all pairs of farms.

    Input

    * Line 1: A single integer, N

    * Lines 2..N+1: Two space-separated integers x and y specifying coordinate of each farm

    Output

    * Line 1: A single integer that is the squared distance between the pair of farms that are farthest apart from each other.

    Sample Input

    4
    0 0
    0 1
    1 1
    1 0
    

    Sample Output

    2
    

    Hint

    Farm 1 (0, 0) and farm 3 (1, 1) have the longest distance (square root of 2) 
  • 相关阅读:
    装饰器
    提供离线chrome谷歌浏览器插件crx的网站有
    关于使用AWS上的RHEL8.x/Redhat系统使用自己单独购买的Redhat官网license导致的yum命令报错处理
    关于aws账单数据中几个重要的与费用相关的字段的意义分析
    在vCenter或者ESXi中通过ova/ovf进行还原部署虚拟机的过程记录
    关于python爬虫request.get()方法的常用参数
    关于aws cli命令的exit/return code分析
    关于pycharm代码运行后控制台的输出不完整被截断的处理
    关于变量的值中包含另一个变量引用的处理间接变量引用
    关于在python中使用pandas模块将列表list/元组tuple写入excel中
  • 原文地址:https://www.cnblogs.com/Skyxj/p/3351839.html
Copyright © 2011-2022 走看看