Rotating Scoreboard POJ - 3335 (半平面交)
Rotating Scoreboard
题意:给你多边形坐标,问你多面性内部有没有区域放置一个记分牌使得多边形周围坐的人都能看见,相切也可
思路:就是求多边形是否有内核,半平面交,题目是顺时针输入,要变成逆时针
1 // 2 // Created by HJYL on 2020/2/6. 3 // 4 #include<iostream> 5 #include<stdio.h> 6 #include<algorithm> 7 #include<math.h> 8 using namespace std; 9 typedef long long ll; 10 typedef double db; 11 const int N=207; 12 const db eps=1e-7; 13 int sign(db k){if(k>eps) return 1;if(k<-eps) return -1; return 0;} 14 int dcmp(db k1,db k2){return sign(k1-k2);} 15 struct point{ 16 db x,y; 17 point operator - (const point &k)const{ 18 return (point){x-k.x,y-k.y}; 19 } 20 point operator + (const point &k)const{ 21 return (point){x+k.x,y+k.y}; 22 } 23 point operator * (const db &k)const{ 24 return (point){x*k,y*k}; 25 } 26 point operator / (const db &k)const{ 27 return (point){x/k,y/k}; 28 } 29 db angle(){return atan2(y,x);} 30 void print(){printf("(%f,%f)\n",x,y);} 31 }P[N]; 32 db cross(point k1,point k2){ 33 return k1.x*k2.y-k1.y*k2.x; 34 } 35 db dot(point k1,point k2){ 36 return k1.x*k2.x+k1.y*k2.y; 37 } 38 struct line{ 39 point s,e; 40 db angle(){return (e-s).angle();} 41 }L[N],dq[N]; 42 point getLL(line k1,line k2){ 43 db w1=cross(k1.s-k2.s,k2.e-k2.s),w2=cross(k2.e-k2.s,k1.e-k2.s); 44 return (k1.s*w2+k1.e*w1)/(w1+w2); 45 } 46 bool onRight(line k,point p){ 47 return sign((cross(p-k.s,k.e-k.s)))>0; 48 } 49 bool cmp(line k1,line k2){ 50 if(dcmp(k1.angle(),k2.angle())==0) return onRight(k2,k1.s); 51 return k1.angle()<k2.angle(); 52 } 53 int n,tot; 54 bool halfplaneinsert(){ 55 sort(L+1,L+1+tot,cmp); 56 int cnt=0; 57 for(int i=1;i<=tot;i++){ 58 if(i<tot&&dcmp(L[i].angle(),L[i+1].angle())==0) continue; 59 L[++cnt]=L[i]; 60 } 61 int tail=-1,head=0; 62 for(int i=1;i<=cnt;i++){ 63 while(tail-head>=1&&onRight(L[i],getLL(dq[tail],dq[tail-1]))) tail--; 64 while(tail-head>=1&&onRight(L[i],getLL(dq[head],dq[head+1]))) head++; 65 dq[++tail]=L[i]; 66 } 67 while(tail-head>=1&&onRight(dq[head],getLL(dq[tail],dq[tail-1]))) tail--; 68 while(tail-head>=1&&onRight(dq[tail],getLL(dq[head],dq[head+1]))) head++; 69 return tail-head>=2; 70 } 71 int main() 72 { 73 int t; 74 scanf("%d",&t); 75 while(t--){ 76 scanf("%d",&n); 77 for(int i=1;i<=n;i++){ 78 scanf("%lf%lf",&P[i].x,&P[i].y); 79 } 80 tot=0; 81 for(int i=n;i>1;i--){ 82 L[++tot]=(line){P[i],P[i-1]}; 83 } 84 L[++tot]=(line){P[1],P[n]}; 85 if(halfplaneinsert()) printf("YES\n"); 86 else printf("NO\n"); 87 } 88 }