• POJ 1228


    给题意跪了。。。

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

    得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点。

    这样,只需判断每条边是否有大于等于三点即可。注意,一条直线的凸包是NO

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    struct point {
    	int x,y;
    }p[1050];
    int n;
    int stop,cnt;
    int ans[1050],st[1050];
    
    bool cmp(point A,point B){
    	if(A.y<B.y) return true;
    	else if(A.y==B.y){
    		if(A.x<B.x) return true;
    	}
    	return false;
    }
    
    bool multi(point a,point b,point c){
    	return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x)>0;
    }
    
    void slove(){
    	stop=cnt=0;
    	st[stop++]=0; st[stop++]=1;
    	for(int i=2;i<n;i++){
    		while(stop>1&&multi(p[i],p[st[stop-1]],p[st[stop-2]])) stop--;
    		st[stop++]=i;
    	}
    	for(int i=0;i<stop;i++)
    	ans[cnt++]=st[i];
    	stop=0;
    	st[stop++]=n-1; st[stop++]=n-2;
    	for(int i=n-3;i>=0;i--){
    		while(stop>1&&multi(p[i],p[st[stop-1]],p[st[stop-2]])) stop--;
    		st[stop++]=i;
    	}
    	for(int i=1;i<stop;i++)
    	ans[cnt++]=st[i];
    }
    
    
    int main(){
    	int t;
    	scanf("%d",&t);
    	while(t--){
    		scanf("%d",&n);
    		for(int i=0;i<n;i++){
    			scanf("%d%d",&p[i].x,&p[i].y);
    		}
    		sort(p,p+n,cmp);
    		slove();
    /*		for(int i=0;i<cnt;i++){
    			cout<<p[ans[i]].x<<' '<<p[ans[i]].y<<endl;
    		}*/
    		if(n==1||n==2) { printf("NO
    "); continue; }
    		bool flag=true; point s,t,e; int k;
    		s=p[ans[0]]; t=p[ans[1]];
    		int j;
    		for(j=2;j<cnt;j++){
    			e=p[ans[j]];
    			if((e.x-s.x)*(t.y-s.y)-(e.y-s.y)*(t.x-s.x)!=0){
    				break;
    			}
    		}
    		if(j>=cnt) { printf("NO
    "); continue; }
    		for(int i=0;;i=k-1){
    			s=p[ans[i]];t=p[ans[++i]];
    			if(i+1>=cnt){ flag=false; break; }
    		 	e=p[ans[i+1]];
    			if((e.x-s.x)*(t.y-s.y)-(e.y-s.y)*(t.x-s.x)!=0){
    				flag=false;
    				break;
    			}
    			k=i+1;
    			while(true){
    				e=p[ans[k]];
    				if((e.x-s.x)*(t.y-s.y)-(e.y-s.y)*(t.x-s.x)!=0){
    					break;
    				}
    				k++;
    				if(k>=cnt) break;
    			}
    			if(k>=cnt) break;
    		}
    		if(flag) printf("YES
    ");
    		else printf("NO
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    android的HTTP框架之Volley
    android学习笔记五。2、其他组件
    android学习笔记四
    android学习笔记二、Activity深入学习
    android事件学习
    android之handler机制深入解析
    java线程深入学习
    K-Means
    git fetch + merge与 git pull的区别
    git分支管理
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3883602.html
Copyright © 2020-2023  润新知