凸包稳定性判断:每条边上是否至少有三点 POJ 1228

  1 //凸包稳定性判断:每条边上是否至少有三点
  2 // POJ 1228
  3 
  4 #include <iostream>
  5 #include <cstdio>
  6 #include <cstdlib>
  7 #include <algorithm>
  8 #include <vector>
  9 #include <math.h>
 10 using namespace std;
 11 #define LL long long
 12 typedef pair<int,int> pii;
 13 const double inf = 0x3f3f3f3f;
 14 const LL MOD =100000000LL;
 15 const int N =110;
 16 #define clc(a,b) memset(a,b,sizeof(a))
 17 const double eps = 1e-8;
 18 void fre() {freopen("in.txt","r",stdin);}
 19 void freout() {freopen("out.txt","w",stdout);}
 20 inline int read() {int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();}while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
 21 
 22 int sgn(double x){
 23     if(fabs(x) < eps)return 0;
 24     if(x < 0)return -1;
 25     else return 1;
 26 }
 27 
 28 struct Point{
 29     double x,y;
 30     Point(){}
 31     Point(double _x,double _y){
 32         x = _x;y = _y;
 33     }
 34     Point operator -(const Point &b)const{
 35         return Point(x - b.x,y - b.y);
 36     }
 37     double operator ^(const Point &b)const{
 38         return x*b.y - y*b.x;
 39     }
 40     double operator *(const Point &b)const{
 41         return x*b.x + y*b.y;
 42     }
 43     friend bool operator<(const Point &a,const Point &b){
 44         if(fabs(a.y-b.y)<eps) return a.x<b.x;
 45         return a.y<b.y;
 46     }
 47     friend double dis2(Point a){
 48         return a.x*a.x+a.y*a.y;
 49     }
 50 };
 51 
 52 double dis(Point a,Point b){
 53     return sqrt(dis2(a-b));
 54 }
 55 
 56 int mult(Point a,Point b,Point o){
 57     return sgn((a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y));
 58 }
 59 //返回top个点
 60 int graham(Point p[],int n,Point q[]){
 61      int top=1;
 62      sort(p,p+n);
 63      if(n==0) return 0;
 64      q[0]=p[0];
 65      if(n==1) return 1;
 66      q[1]=p[1];
 67      if(n==2) return 2;
 68      q[2]=p[2];
 69      for(int i=2;i<n;i++){
 70          while(top&&(mult(p[i],q[top],q[top-1])>0)) top--;
 71          q[++top]=p[i];
 72      }
 73      int len=top;
 74      q[++top]=p[n-2];
 75      for(int i=n-3;i>=0;i--){
 76          while(top!=len&&(mult(p[i],q[top],q[top-1])>0)) top--;
 77          q[++top]=p[i];
 78      }
 79      return top;
 80 }
 81 
 82 // 判断凸包边上是否至少有三点
 83 bool judge(Point p[],int m){
 84     p[m]=p[0];
 85     p[m+1]=p[1];
 86     for(int i=1;i<m;i++){
 87        if(mult(p[i-1],p[i+1],p[i])!=0&&mult(p[i],p[i+2],p[i+1])!=0)
 88         return false;
 89     }
 90     return true;
 91 }
 92 
 93 
 94 Point p[1011];
 95 Point ch[1011];
 96 int main(){
 97     // fre();
 98     int T;
 99     scanf("%d",&T);
100     while(T--){
101        int n;
102        scanf("%d",&n);
103        for(int i=0;i<n;i++){
104            double x,y;
105            scanf("%lf%lf",&x,&y);
106            p[i]=Point(x,y);
107        }
108        int m=graham(p,n,ch);
109        if(n<6) {
110         puts("NO");
111         continue;
112        }
113        if(judge(ch,m)) puts("YES");
114        else puts("NO");
115     }
116     return 0;
117 }
原文地址:https://www.cnblogs.com/ITUPC/p/5895921.html