题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6590
题目大意(来自队友):二维平面上有\(n\)个点,每个点要么是黑色要么是白色,问能否找到一条直线将平面分割成黑白两部分
题解:分别对每种颜色的点求凸包,判断是否相交即可。
(有模板真好)
1 #include<bits/stdc++.h> 2 //#include<cstdio> 3 //#include<cmath> 4 //#include<algorithm> 5 using namespace std; 6 typedef long double lod; 7 typedef long long ll; 8 typedef long double ld; 9 const ld eps=1e-12; 10 const ld pi=acos(-1.0); 11 int sgn(ld x) 12 { 13 if (x<-eps) return -1; 14 if (x>eps) return 1; 15 return 0; 16 } 17 18 struct P; 19 struct LINE; 20 struct CIRCLE; 21 struct TRIANGLE; 22 struct POLYGON; 23 24 void kr(ld &x) 25 { 26 double t; scanf("%lf",&t); 27 x=t; 28 } 29 void kr(ll &x) 30 { 31 scanf("%lld",&x); 32 } 33 struct P 34 { 35 lod x,y; 36 void read() 37 { 38 kr(x); kr(y); 39 } 40 P operator+(const P &t)const 41 { 42 return {x+t.x,y+t.y}; 43 } 44 P operator-(const P &t)const 45 { 46 return {x-t.x,y-t.y}; 47 } 48 P operator*(ld t)const 49 { 50 return {x*t,y*t}; 51 } 52 P operator/(ld t)const 53 { 54 return {x/t,y/t}; 55 } 56 lod operator*(const P &t)const 57 { 58 return x*t.y-y*t.x; 59 } 60 lod operator%(const P &t)const 61 { 62 return x*t.x+y*t.y; 63 } 64 bool operator<(const P &t)const 65 { 66 return sgn(x-t.x)<0||sgn(x-t.x)==0&&sgn(y-t.y)<0; 67 } 68 bool operator==(const P &t)const 69 { 70 return sgn(x-t.x)==0&&sgn(y-t.y)==0; 71 } 72 ld ang()const 73 { 74 return atan2(y,x); 75 } 76 ld length()const 77 { 78 return sqrt(x*x+y*y); 79 } 80 P rotate(const P &t,ld sita)const 81 { 82 return {(x-t.x)*cos(sita)-(y-t.y)*sin(sita)+t.x, 83 (x-t.x)*sin(sita)+(y-t.y)*cos(sita)+t.y}; 84 } 85 ld btang(const P &t)const 86 { 87 return acos( (*this%t)/length()/t.length() ); 88 } 89 P midvec(const P &t)const 90 { 91 return (*this)/length()+t/t.length(); 92 } 93 }; 94 95 struct LINE 96 { 97 P p1,p2; 98 void read() 99 { 100 p1.read(); p2.read(); 101 } 102 LINE midLINE() 103 { 104 P midp=(p1+p2)/2; 105 P v=p2-p1; 106 v=v.rotate({0,0},pi/2); 107 return {midp,midp+v}; 108 } 109 bool have1(const P &p)const 110 { 111 return sgn( (p-p1)*(p-p2) )==0&&sgn( (p-p1)%(p-p2) )<=0; 112 } 113 bool have2(const P &p)const 114 { 115 return sgn( (p-p1)*(p-p2) )==0&&sgn( (p-p1)%(p2-p1) )>=0; 116 } 117 bool have3(const P &p)const 118 { 119 return sgn( (p-p1)*(p-p2) )==0; 120 } 121 lod areawith(const P &p)const 122 { 123 return abs( (p1-p)*(p2-p)/2 ); 124 } 125 P vecfrom(const P &p)const 126 { 127 P v=(p2-p1); 128 v=v.rotate({0,0},pi/2); 129 ld s1=(p1-p)*(p2-p); 130 ld s2=v*(p2-p1); 131 v=v*(s1/s2); 132 return v; 133 } 134 P footfrom(const P &p)const 135 { 136 P v=vecfrom(p); 137 return p+v; 138 } 139 ld dis1from(const P &p)const 140 { 141 P foot=footfrom(p); 142 if (have1(foot)) return (foot-p).length(); 143 return min( (p1-p).length(),(p2-p).length()); 144 } 145 ld dis2from(const P &p)const 146 { 147 P foot=footfrom(p); 148 if (have2(foot)) return (foot-p).length(); 149 return (p1-p).length(); 150 } 151 ld dis3from(const P &p)const 152 { 153 return vecfrom(p).length(); 154 } 155 P symP(const P &p)const 156 { 157 P v=vecfrom(p); 158 return p+v*2; 159 } 160 bool isct11(const LINE &L)const 161 { 162 P a1=p1,a2=p2; 163 P b1=L.p1,b2=L.p2; 164 if (sgn( max(a1.x,a2.x)-min(b1.x,b2.x) )<0|| 165 sgn( max(b1.x,b2.x)-min(a1.x,a2.x) )<0|| 166 sgn( max(a1.y,a2.y)-min(b1.y,b2.y) )<0|| 167 sgn( max(b1.y,b2.y)-min(a1.y,a2.y) )<0) 168 return 0; 169 lod tmp1=(a2-a1)*(b1-a1); 170 lod tmp2=(a2-a1)*(b2-a1); 171 if (sgn(tmp1)<0&&sgn(tmp2)<0||sgn(tmp1)>0&&sgn(tmp2)>0) return 0; 172 tmp1=(b2-b1)*(a1-b1); 173 tmp2=(b2-b1)*(a2-b1); 174 if (sgn(tmp1)<0&&sgn(tmp2)<0||sgn(tmp1)>0&&sgn(tmp2)>0) return 0; 175 return 1; 176 } 177 bool isct21(const LINE &L)const 178 { 179 P v=p2-p1; 180 P a=p1; 181 P b1=L.p1,b2=L.p2; 182 lod tmp1=v*(b1-a); 183 lod tmp2=v*(b2-a); 184 if (sgn(tmp1)<0&&sgn(tmp2)<0||sgn(tmp1)>0&&sgn(tmp2)>0) return 0; 185 if (tmp1>tmp2) swap(b1,b2); 186 if (sgn( (b1-a)*(b2-a) )>0) return 1; 187 if (sgn( (b1-a)*(b2-a) )<0) return 0; 188 return L.have1(a)||have2(b1)||have2(b2); 189 } 190 bool isct31(const LINE &L)const 191 { 192 P v=p2-p1; 193 P a=p1; 194 lod tmp1=v*(L.p1-a); 195 lod tmp2=v*(L.p2-a); 196 if (sgn(tmp1)<0&&sgn(tmp2)<0||sgn(tmp1)>0&&sgn(tmp2)>0) return 0; 197 return 1; 198 } 199 bool isct22(const LINE &L)const 200 { 201 if (have2(L.p1)||L.have2(p1)) return 1; 202 P v=vecfrom(L.p1); 203 if (sgn( v%(L.p2-L.p1) )<=0) return 0; 204 v=L.vecfrom(p1); 205 if (sgn( v%(p2-p1) )<=0) return 0; 206 return 1; 207 } 208 bool isct32(const LINE &L)const 209 { 210 if (have3(L.p1)) return 1; 211 P v=vecfrom(L.p1); 212 if (sgn( v%(L.p2-L.p1) )<=0) return 0; 213 return 1; 214 } 215 bool isct33(const LINE &L)const 216 { 217 if (have3(L.p1)) return 1; 218 return sgn( (p2-p1)*(L.p2-L.p1) )!=0; 219 } 220 ld dis33(const LINE &L)const 221 { 222 return (L.p1-p1)*(L.p2-p1) / ( (p2-p1)*(L.p2-L.p1) ) 223 * (p2-p1).length(); 224 } 225 P isctPoint(const LINE &L)const 226 { 227 ld len=dis33(L); 228 P v=p2-p1; 229 return p1+v*(len/v.length()); 230 } 231 232 }; 233 234 const int POLNUM=1005; 235 struct PL 236 { 237 ld len; 238 int v; 239 }stk[POLNUM]; 240 int top; 241 bool cmplen(const PL &a,const PL &b) 242 { 243 return a.len<b.len; 244 } 245 P cent; 246 bool cmpang(const P &p1,const P &p2) 247 { 248 int tmp=sgn( (p1-cent).ang() - (p2-cent).ang() ); 249 if (tmp!=0) return tmp<0; 250 return (p1-cent).length() < (p2-cent).length(); 251 } 252 struct POLYGON 253 { 254 int n; 255 P a[POLNUM]; 256 void read(int k) 257 { 258 for (int i=1;i<=k;i++) a[i].read(); 259 n=k; 260 } 261 void ChangetoConvex() 262 { 263 for (int i=2;i<=n;i++) 264 if (a[i].x<a[1].x||a[i].x==a[1].x&&a[i].y<a[1].y) 265 swap(a[1],a[i]); 266 cent=a[1]; 267 sort(a+2,a+n+1,cmpang); 268 int top=2; 269 for (int i=3;i<=n;i++) 270 { 271 while(top>=2&& 272 sgn((a[top]-a[top-1])*(a[i]-a[top]))<=0 ) 273 top--; 274 a[++top]=a[i]; 275 } 276 n=top; 277 } 278 ld Clength()const 279 { 280 ld ret=0; 281 for (int i=2;i<=n;i++) ret+=(a[i]-a[i-1]).length(); 282 if (n>2) ret+=(a[1]-a[n]).length(); 283 return ret; 284 } 285 bool have(const P p) 286 { 287 int k,d1,d2,wn=0; 288 a[0]=a[n]; 289 for (int i=1;i<=n;i++) 290 { 291 LINE L={a[i-1],a[i]}; 292 if (L.have1(p)) return 1; 293 k=sgn( (a[i]-a[i-1])*(p-a[i-1]) ); 294 d1=sgn( a[i-1].y-p.y ); 295 d2=sgn( a[i].y-p.y ); 296 if (k>0&&d1<=0&&d2>0) wn++; 297 if (k<0&&d2<=0&&d1>0) wn--; 298 } 299 return wn!=0; 300 } 301 ld cutlength(const LINE &L) 302 { 303 a[0]=a[n]; top=0; 304 for (int i=1;i<=n;i++) 305 { 306 LINE R={a[i-1],a[i]}; 307 lod s1=sgn( (L.p2-L.p1)*(R.p1-L.p1) ); 308 lod s2=sgn( (L.p2-L.p1)*(R.p2-L.p1) ); 309 if (s1<0&&s2<0||s1==0&&s2==0||s1>0&&s2>0) continue; 310 if (s1<s2) stk[++top]={L.dis33(R),(s1!=0&&s2!=0?2:1)}; 311 else stk[++top]={L.dis33(R),(s1!=0&&s2!=0?-2:-1)}; 312 } 313 sort(stk+1,stk+top+1,cmplen); 314 int cnt=0; 315 ld ret=0; 316 for (int i=1;i<=top;i++) 317 { 318 if (cnt) ret+=stk[i].len-stk[i-1].len; 319 cnt+=stk[i].v; 320 } 321 return ret; 322 } 323 bool isct(const POLYGON &POL)const 324 { 325 for (int i=2;i<=n;i++) 326 for (int j=2;j<=POL.n;j++) 327 { 328 LINE L1={a[i-1],a[i]}; 329 LINE L2={POL.a[j-1],POL.a[j]}; 330 if (L1.isct11(L2)) return 1; 331 } 332 return 0; 333 } 334 ld isctarea(const POLYGON &POL)const; 335 }; 336 337 int T,n,f[101]; 338 P p[101]; 339 POLYGON a,b; 340 int init() 341 { 342 a.n=b.n=0; 343 scanf("%d",&n); 344 for(int i=1;i<=n;i++) 345 { 346 p[i].read(); 347 scanf("%d",&f[i]); 348 if(f[i]>0)a.a[++a.n]=p[i]; 349 else b.a[++b.n]=p[i]; 350 } 351 if(a.n>b.n)swap(a,b); 352 if(!a.n)return printf("Successful!\n"),0; 353 if(b.n==1) 354 { 355 if((a.a[1]-b.a[1]).length()<eps)return printf("Infinite loop!\n"),0; 356 return printf("Successful!\n"),0; 357 } 358 b.ChangetoConvex(); 359 for(int i=1;i<=a.n;i++) 360 if(b.have(a.a[i]))return printf("Infinite loop!\n"),0; 361 a.ChangetoConvex(); 362 if(a.isct(b))return printf("Infinite loop!\n"),0; 363 return printf("Successful!\n"),0; 364 } 365 int main() 366 { 367 scanf("%d",&T); 368 while(T--)init(); 369 return 0; 370 }
原文地址:https://www.cnblogs.com/DeaphetS/p/11229212.html
时间: 2024-11-09 08:37:32