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 101128 F.Landscaping最小割--还不懂

dp+分类讨论 Gym 101128E

Gym 101128F Sheldon Numbers(网络流)

很好的脑洞题:dfs+暴力 Gym - 101128A Promotions

Gym 101128 B Black Vienna