zoukankan      html  css  js  c++  java
  • poj 1228 Grandpa's Estate 给定了一个凸包的部分顶点和边上的点,判断是否能唯一确定一个凸包

    题目来源: 

    http://poj.org/problem?id=1228

    题意:题目输入一个凸包上的点(没有凸包内部的点,要么是凸包顶点,要么是凸包边上的点),判断这个凸包是否唯一。所谓唯一就是判断能不能在原有凸包上加点,

     得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点。很容易得到,当一个凸包唯一时,凸包的每条边上都要有至少三个点,若只有两个点,则可以增加一个点,得到更大的凸包。

    思路:直接求凸包,得到原来凸包顶点,去掉凸包边上的点,由于用graham求凸包的过程中要对点集List[]极角排序,最后只需判断求得的凸包上的点stack[]  本来在 原点集List[]按极角排序后的位置是否相邻,由于凸包的性质,需要特别判断 凸包中第一个和最后一个点 它们之间是否有点。 另外, 若求得凸包中的点个数为2,则输入的所有点都在一条线上,这时需输出NO。

    代码如下:

    #include <iostream>
    #include <algorithm>
    #include <stdlib.h>
    #include <iostream>
    #include <stdio.h>
    #include <stack>
    #include <string>
    #include <string.h>
    #include <algorithm>
    #include <stdlib.h>
    #include <vector>
    #include <set>
    #include <math.h>
    #include <cmath>
    #include <map>
    #include <queue>
    using namespace std ;
    typedef long long LL;
    const int N = 1010;
    double EPS= 1e-10;
    double add(double a, double b)
    {
        if( fabs(a+b)< EPS * ( fabs(a)+fabs(b) ) )  return 0;
        return a+b;
    }
    struct Point{
        double x,y;
        Point(){}
        Point(double _x, double _y):x(_x),y(_y){}
        Point operator + (Point p){
            return Point( add(x,p.x), add( y,p.y ) );
        }
        Point operator -(Point p){
            return Point( add(x,-p.x), add(y, -p.y) );
        }
        double operator^(Point p){
            return add(x*p.y, -y*p.x );
        }
        friend istream& operator>>(istream& is, Point& p){
            is>>p.x>>p.y;
            return is;
        }
        double dist(Point p){
            return sqrt( add( ( x-p.x)*(x-p.x) , (y-p.y)*(y-p.y) ) );
        }
    };
    Point List[N]; // 点集
    int top;  // 栈顶指针
    int state[N]; // 栈中放的凸包点 原本 在点集按极角排序后的点集合中的位置(指针)
    bool cmp(Point a, Point b) // 按y轴值从小到大, y轴值相同时,x轴从小到大排列
    {
        if(a.y != b.y) return a.y < b.y;
        else  return a.x < b.x;
    }
    bool operator < (Point a, Point b) // 极角排序
    {
        double tmp= (a-List[0])^(b-List[0]);
        if(tmp > 0) return 1;
        else if(tmp== 0 && a.dist(List[0]) <b.dist(List[0])  ) return 1;
        return 0;
    }
    void init(int n)
    {
        for(int i=0 ; i<n ;i++)
            cin>>List[i];
        sort(List, List+n,cmp);// 排序后 List[0]为最左下方的点
        sort(List+1 , List+n ); // 对List[1,n-1] 中的点进行极角排序,为凸包做准备
    }
    void graham(int n)
    {
       state[0]=0;
       state[1]=1;
       top=1;
       double t;
        for(int i=2 ; i< n ; i++){
            while(top >= 1 && ( (List[state[top] ]-List[ state[top-1] ] )^(List[i]-List[ state[top-1]] ) ) <=0 )
                top--; // 不是凸包中的点出栈
            top++;// 点i进栈
            state[top]=i; // 记录点i进栈的 原本位置 i
        }
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            memset(state,-1,sizeof(state));
            cin>>n;
            init(n);
            graham(n);
            if(top==1)
            {
                printf("NO
    ");
                continue;
            }
            int i;
            int flag=0;
            for( i=1; i<= top; i++) // 判断凸包顶点【0-1-2-...-top】是否相邻
            {
                if( (state[i-1] +1) == state[i]  ){
                    flag=1;
                    break;
                }
            }
            for(i=1 ; i<n-1 ; i++) // 判断 凸包中最后一个顶点和 第一个顶点是否相邻
            {
                if( ((List[n-1]-List[0])^(List[i]-List[0])) == 0 )
                    break;
            }
            if(i <n-1 && !flag ) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    poj1837 Balance

    字符流
    字节流
    File类
    this和static
    异常
    接口
    抽象类
    多态
  • 原文地址:https://www.cnblogs.com/zn505119020/p/3644088.html
Copyright © 2011-2022 走看看