zoukankan      html  css  js  c++  java
  • POJ1228(稳定凸包问题)

    题目:Grandpa's Estate

     

    题意:输入一个凸包上的点(没有凸包内部的点,要么是凸包顶点,要么是凸包边上的点),判断这个凸包是否稳定。所谓稳

    定就是判断能不能在原有凸包上加点,得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点。

     

    分析:容易知道,当一个凸包稳定时,凸包的每条边上都要有至少三个点,若只有两个点,则可以增加一个点,得到更大的凸

    包。这样我们可以求出凸包,在求凸包时把共线的点也加进来,这样我们就判断是否有连续的三点共线即可,具体参见代码。

    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <math.h>
    
    using namespace std;
    
    const int N = 40005;
    
    typedef double DIY;
    
    struct Point
    {
        DIY x,y;
    };
    
    Point p[N];
    Point stack[N];
    Point MinA;
    
    int top;
    
    DIY dist(Point A,Point B)
    {
        return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
    }
    
    DIY cross(Point A,Point B,Point C)
    {
        return (B.x-A.x)*(C.y-A.y)-(B.y-A.y)*(C.x-A.x);
    }
    
    bool cmp(Point a,Point b)
    {
        DIY k=cross(MinA,a,b);
        if(k>0) return 1;
        if(k<0) return 0;
        return dist(MinA,a)<dist(MinA,b);  //这里共线的点按距离从小到大排序
    }
    
    void Graham(int n)
    {
        int i;
        for(i=1; i<n; i++)
            if(p[i].y<p[0].y||(p[i].y==p[0].y&&p[i].x<p[0].x))
                swap(p[i],p[0]);
        MinA=p[0];
        sort(p+1,p+n,cmp);
        stack[0]=p[0];
        stack[1]=p[1];
        top=1;
        for(i=2; i<n; i++)
        {
            //注意这里我们把共线的点也压入凸包里
            while(cross(stack[top-1],stack[top],p[i])<0&&top>=1) --top;
            stack[++top]=p[i];
        }
    }
    
    bool Judge()
    {
        for(int i=1;i<top;i++)
        {
            //判断凸包的一条边上是否至少有3点
            if((cross(stack[i-1],stack[i+1],stack[i]))!=0&&(cross(stack[i],stack[i+2],stack[i+1]))!=0)
                return false;
        }
        return true;
    }
    
    int main()
    {
        int t,n,i;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(i=0;i<n;i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            if(n<6)
            {
                puts("NO");
                continue;
            }
            Graham(n);
            cout<<endl;
            for(i=0;i<n;i++)
              cout<<p[i].x<<" "<<p[i].y<<endl;
            cout<<endl;
            for(i=0;i<=top;i++)
              cout<<stack[i].x<<" "<<stack[i].y<<endl;
            if(Judge()) puts("YES");
            else        puts("NO");
        }
        return 0;
    }
    


     

  • 相关阅读:
    《程序员修炼之道+从小工到专家》读后感2
    java在子类中,调用父类中被覆盖的方法
    长按文本全复制
    NSTimer 定时器总结
    对URL编码
    Mysql find_in_set 效率问题
    php 运算符优先级
    使用layui上传控件问题
    xcode11发版一直卡在App Store验证过不去
    iOS13禁用深色模式
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3265279.html
Copyright © 2011-2022 走看看