大致题意:
给出一个凸包,以及凸包内的两个点p1,p2,求有多少条经过凸包顶点的直线能够将凸包分割为两部分,且给出的两点分别属于不同的部分
枚举凸包的顶点,二分求出p1,p2线段左边的最大坐标L以及右边的最小坐标R,则答案为R-L-1的累加和除以2
注意文件输入,输出
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<set> 7 #include<map> 8 #include<stack> 9 #include<time.h> 10 #include<cstdlib> 11 #include<cmath> 12 #include<list> 13 using namespace std; 14 #define MAXN 100100 15 #define eps 1e-9 16 #define For(i,a,b) for(int i=a;i<=b;i++) 17 #define Fore(i,a,b) for(int i=a;i>=b;i--) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 #define mkp make_pair 21 #define pb push_back 22 #define cr clear() 23 #define sz size() 24 #define met(a,b) memset(a,b,sizeof(a)) 25 #define iossy ios::sync_with_stdio(false) 26 #define fre freopen 27 #define pi acos(-1.0) 28 #define inf 1e6+7 29 #define Vector Point 30 const int Mod=1e9+7; 31 typedef unsigned long long ull; 32 typedef long long ll; 33 int dcmp(double x){ 34 if(fabs(x)<=eps) return 0; 35 return x<0?-1:1; 36 } 37 struct Point{ 38 double x,y; 39 int id; 40 Point(double x=0,double y=0):x(x),y(y) {} 41 bool operator < (const Point &a)const{ 42 if(x==a.x) return y<a.y; 43 return x<a.x; 44 } 45 Point operator - (const Point &a)const{ 46 return Point(x-a.x,y-a.y); 47 } 48 Point operator + (const Point &a)const{ 49 return Point(x+a.x,y+a.y); 50 } 51 Point operator * (const double &a)const{ 52 return Point(x*a,y*a); 53 } 54 Point operator / (const double &a)const{ 55 return Point(x/a,y/a); 56 } 57 void read(){ 58 scanf("%lf%lf",&x,&y); 59 } 60 void out(){ 61 cout<<"debug: "<<x<<" "<<y<<endl; 62 } 63 bool operator == (const Point &a)const{ 64 return dcmp(x-a.x)==0 && dcmp(y-a.y)==0; 65 } 66 }; 67 double Dot(Vector a,Vector b) { 68 return a.x*b.x+a.y*b.y; 69 } 70 double dis(Vector a) { 71 return sqrt(Dot(a,a)); 72 } 73 double Cross(Point a,Point b){ 74 return a.x*b.y-a.y*b.x; 75 } 76 int n; 77 Point p[200005]; 78 int ls,rs; 79 int chk1(Point p1,Point p2,int pos){ 80 int l=pos+1,r=pos+n-1; 81 while(l<r){ 82 int mid=l+r>>1; 83 if(dcmp(Cross(p[mid]-p[pos],p1-p[pos]))<=0 && dcmp(Cross(p[mid]-p[pos],p2-p[pos])<=0)) r=mid; 84 else l=mid+1; 85 } 86 return l; 87 } 88 int chk2(Point p1,Point p2,int pos){ 89 int l=pos+1,r=pos-1+n; 90 while(l<r){ 91 int mid=l+r+1>>1; 92 if(dcmp(Cross(p[mid]-p[pos],p1-p[pos]))>=0 && dcmp(Cross(p[mid]-p[pos],p2-p[pos]))>=0) l=mid; 93 else r=mid-1; 94 } 95 return l; 96 } 97 Point p1,p2; 98 void solve(){ 99 For(i,1,n) p[i].read(); 100 p1.read();p2.read(); 101 ll ans=0; 102 For(i,1,n) p[i+n]=p[i]; 103 For(i,1,n){ 104 ls=chk1(p1,p2,i); 105 rs=chk2(p1,p2,i); 106 if(ls!=rs)ans+=abs(ls-rs)-1; 107 } 108 cout<<ans/2<<endl; 109 } 110 int main(){ 111 // fre("in.txt","r",stdin); 112 freopen("kingdom.in","r",stdin); 113 freopen("kingdom.out","w",stdout); 114 int t=0; 115 while(~scanf("%d",&n) &&n) solve(); 116 return 0; 117 }