• 【分类讨论】【计算几何】【凸包】hihocoder 1582 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 E. Territorial Dispute


    题意:平面上n个点,问你是否存在一种黑白染色方案,使得对于该方案,无法使用一条直线使得黑色点划分在直线一侧,白色点划分在另一侧。如果存在,输出一种方案。

    如果n<=2,显然不存在。

    如果所有点共线,且n>2,只需交替染色即可。

    设凸包上的点数为K,如果K==n,且n==3,不存在,如果n>3,只需交替染色即可。

    如果K<n,只需凸包上点涂黑,内部点留白即可。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    struct Point{
    	int x,y,id;
    	Point(const int &x,const int &y,const int &id){
    		this->x=x;
    		this->y=y;
    		this->id=id;
    	}
    	Point(const int &x,const int &y){
    		this->x=x;
    		this->y=y;
    	}
    	Point(){}
    	void read(){
    		scanf("%d%d",&x,&y);
    	}
    }p[105],q[105];
    int K;
    typedef Point Vector;
    Vector operator - (const Point &a,const Point &b){
    	return Vector(a.x-b.x,a.y-b.y);
    }
    int Cross(const Vector &a,const Vector &b){
    	return a.x*b.y-a.y*b.x;
    }
    bool cmp(const Point &a,const Point &b){
    	return a.x!=b.x ? a.x<b.x : a.y<b.y;
    }
    int n,T;
    char anss[105];
    int main(){
    	scanf("%d",&T);
    	for(;T;--T){
    		K=0;
    		memset(anss,0,sizeof(anss));
    		scanf("%d",&n);
    		for(int i=0;i<n;++i){
    			p[i].read();
    			p[i].id=i;
    		}
    		sort(p,p+n,cmp);
    		if(n<=2){
    			puts("NO");
    			continue;
    		}
    		bool flag=1;
    		for(int i=1;i<n-1;++i){
    			if(Cross(p[i]-p[i-1],p[i+1]-p[i])!=0){
    				flag=0;
    				break;
    			}
    		}
    		if(flag){
    			puts("YES");
    			for(int i=0;i<n;++i){
    				anss[p[i].id]=(i%2==0 ? 'A' : 'B');
    			}
    			for(int i=0;i<n;++i){
    				putchar(anss[i]);
    			}
    			puts("");
    			continue;
    		}
    		for(int i=0;i<n;++i){
    			while(K>1 && Cross(q[K-1]-q[K-2],p[i]-q[K-1])<0){
    				--K;
    			}
    			q[K++]=p[i];
    		}
    		for(int i=n-2,t=K;i>=0;--i){
    			while(K>t && Cross(q[K-1]-q[K-2],p[i]-q[K-1])<0){
    				--K;
    			}
    			q[K++]=p[i];
    		}
    		--K;
    		if(K<n){
    			for(int i=0;i<K;++i){
    				anss[q[i].id]='A';
    			}
    			for(int i=0;i<n;++i){
    				if(!anss[i]){
    					anss[i]='B';
    				}
    			}
    			puts("YES");
    			for(int i=0;i<n;++i){
    				putchar(anss[i]);
    			}
    			puts("");
    		}
    		else{
    			if(K>3){
    				for(int i=0;i<K;++i){
    					anss[q[i].id]=(i%2==0 ? 'A' : 'B');
    				}
    				puts("YES");
    				for(int i=0;i<n;++i){
    					putchar(anss[i]);
    				}
    				puts("");
    			}
    			else{
    				puts("NO");
    			}
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    最全的.NET Core跨平台微服务学习资源没有之一
    MySQL添加列、删除列,创建主键等常用操作总结
    SQL Server函数之空值处理
    SqlServer中循环和条件语句
    【转载】ASP.NET Core Web 支付功能接入 微信-扫码支付篇
    【转载】ASP.NET Core Web 支付功能接入 支付宝-电脑网页支付篇
    Core知识整理
    C#对接----韵达开发平台--取电子面单
    Cookie 用法
    微信支付V3版本的那些事
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7583439.html
Copyright © 2020-2023  润新知