GYM 101128 J.Saint John Festival(求凸包是否包含点)
Posted 7391_KID
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GYM 101128 J.Saint John Festival(求凸包是否包含点)相关的知识,希望对你有一定的参考价值。
链接:http://codeforces.com/gym/101128
题意:给定两种点A和B,求有多少个B点,满足存在一个由A组成的三角形,将该点包含在内(包括边界)?
分析:计算几何模板题。。存在一个A三角形包含某个点的充要条件是这个点在A凸包内,所以求一下A凸包,然后枚举B点,对凸包的每一条边(逆时针方向取),若B点都在边的左侧,则该点在凸包内,否则不在。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long ll; 7 struct Point{ 8 ll x,y; 9 }; 10 bool Cmp(Point a,Point b){ 11 if(a.x==b.x)return a.y<b.y; 12 return a.x<b.x; 13 } 14 ll Cross(Point &p1,Point &p2,Point &p3){ 15 return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y); 16 } 17 int ConvexHll(Point *p,int n,Point *ch){ 18 sort(p,p+n,Cmp); 19 int m=0; 20 for(int i=0;i<n;i++){ 21 while(m>1&&Cross(ch[m-2],ch[m-1],p[i])<=0)m--; 22 ch[m++]=p[i]; 23 } 24 int k=m; 25 for(int i=n-2;i>=0;i--){ 26 while(m>k&&Cross(ch[m-2],ch[m-1],p[i])<=0)m--; 27 ch[m++]=p[i]; 28 } 29 if(n>1)m--; 30 return m; 31 } 32 Point _La[10005],Sm[50005],La[10005]; 33 int _L,L,S; 34 bool Is_InCH(Point &s){ 35 for(int i=0;i<L-1;i++){ 36 if(Cross(La[i],La[i+1],s)<0)return false; 37 } 38 if(Cross(La[L-1],La[0],s)<0)return false; 39 return true; 40 } 41 int main(){ 42 // freopen("e:\\in.txt","r",stdin); 43 int cnt=0; 44 scanf("%d",&_L); 45 for(int i=0;i<_L;i++)scanf("%d%d",&_La[i].x,&_La[i].y); 46 scanf("%d",&S); 47 for(int i=0;i<S;i++)scanf("%d%d",&Sm[i].x,&Sm[i].y); 48 L=ConvexHll(_La,_L,La); 49 for(int i=0;i<S;i++){ 50 if(Is_InCH(Sm[i]))cnt++; 51 } 52 printf("%d\n",cnt); 53 return 0; 54 }
以上是关于GYM 101128 J.Saint John Festival(求凸包是否包含点)的主要内容,如果未能解决你的问题,请参考以下文章
GYM 101128 F.Landscaping最小割--还不懂
Gym 101128F Sheldon Numbers(网络流)