UVA 11704
题意:
给你两个集合的点,让你求一条线把这些点分成两部分,使得每一部分都包含每个集合点的一半。
题解:
继续通过没据点来枚举半平面~
用那个多添加n-1个元素的方法,写起来真是无脑~
View Code
1 #include <iostream> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cstdio> 5 #include <algorithm> 6 #include <cmath> 7 8 #define N 33333 9 #define EPS 1e-7 10 11 using namespace std; 12 13 const double PI=acos(-1.0); 14 15 struct PO 16 { 17 double x,y,ag; 18 int fg; 19 }p[N<<2]; 20 21 int n,m; 22 23 inline bool cmp(const PO &a,const PO &b) 24 { 25 return a.ag<b.ag; 26 } 27 28 inline int dc(double x) 29 { 30 if(x>EPS) return 1; 31 else if(x<EPS) return -1; 32 return 0; 33 } 34 35 inline void read() 36 { 37 for(int i=1;i<=n;i++) 38 { 39 scanf("%lf%lf",&p[i].x,&p[i].y); 40 p[i].fg=0; 41 } 42 for(int i=1;i<=m;i++) 43 { 44 scanf("%lf%lf",&p[n+i].x,&p[n+i].y); 45 p[i+n].fg=1; 46 } 47 } 48 49 inline void go() 50 { 51 for(int i=1;i<=n+m;i++) 52 { 53 p[i].ag=atan2(p[i].y,p[i].x); 54 if(dc(p[i].ag)<0) p[i].ag+=2*PI; 55 } 56 sort(p+1,p+1+n+m,cmp); 57 for(int i=1;i<=n+m;i++) p[i+n+m]=p[i],p[i+n+m].ag+=2*PI; 58 int p2=2,c[2]={0,0}; c[p[1].fg]++; 59 for(int p1=1;p1<=n+m;p1++) 60 { 61 while(dc(fabs(p[p2].ag-p[p1].ag)-PI)<=0) 62 { 63 c[p[p2].fg]++; 64 p2++; 65 } 66 if(c[0]==n/2&&c[1]==m/2) {puts("YES");return;} 67 c[p[p1].fg]--; 68 } 69 puts("NO"); 70 } 71 72 int main() 73 { 74 while(scanf("%d%d",&n,&m)!=EOF) 75 { 76 if(n==-1&&m==-1) break; 77 read(),go(); 78 } 79 return 0; 80 }
没有人能阻止我前进的步伐,除了我自己!