题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6590

题目大意(来自队友):二维平面上有\(n\)个点,每个点要么是黑色要么是白色,问能否找到一条直线将平面分割成黑白两部分

题解:分别对每种颜色的点求凸包,判断是否相交即可。

(有模板真好)

 #include<bits/stdc++.h>
//#include<cstdio>
//#include<cmath>
//#include<algorithm>
using namespace std;
typedef long double lod;
typedef long long ll;
typedef long double ld;
const ld eps=1e-;
const ld pi=acos(-1.0);
int sgn(ld x)
{
if (x<-eps) return -;
if (x>eps) return ;
return ;
} struct P;
struct LINE;
struct CIRCLE;
struct TRIANGLE;
struct POLYGON; void kr(ld &x)
{
double t; scanf("%lf",&t);
x=t;
}
void kr(ll &x)
{
scanf("%lld",&x);
}
struct P
{
lod x,y;
void read()
{
kr(x); kr(y);
}
P operator+(const P &t)const
{
return {x+t.x,y+t.y};
}
P operator-(const P &t)const
{
return {x-t.x,y-t.y};
}
P operator*(ld t)const
{
return {x*t,y*t};
}
P operator/(ld t)const
{
return {x/t,y/t};
}
lod operator*(const P &t)const
{
return x*t.y-y*t.x;
}
lod operator%(const P &t)const
{
return x*t.x+y*t.y;
}
bool operator<(const P &t)const
{
return sgn(x-t.x)<||sgn(x-t.x)==&&sgn(y-t.y)<;
}
bool operator==(const P &t)const
{
return sgn(x-t.x)==&&sgn(y-t.y)==;
}
ld ang()const
{
return atan2(y,x);
}
ld length()const
{
return sqrt(x*x+y*y);
}
P rotate(const P &t,ld sita)const
{
return {(x-t.x)*cos(sita)-(y-t.y)*sin(sita)+t.x,
(x-t.x)*sin(sita)+(y-t.y)*cos(sita)+t.y};
}
ld btang(const P &t)const
{
return acos( (*this%t)/length()/t.length() );
}
P midvec(const P &t)const
{
return (*this)/length()+t/t.length();
}
}; struct LINE
{
P p1,p2;
void read()
{
p1.read(); p2.read();
}
LINE midLINE()
{
P midp=(p1+p2)/;
P v=p2-p1;
v=v.rotate({,},pi/);
return {midp,midp+v};
}
bool have1(const P &p)const
{
return sgn( (p-p1)*(p-p2) )==&&sgn( (p-p1)%(p-p2) )<=;
}
bool have2(const P &p)const
{
return sgn( (p-p1)*(p-p2) )==&&sgn( (p-p1)%(p2-p1) )>=;
}
bool have3(const P &p)const
{
return sgn( (p-p1)*(p-p2) )==;
}
lod areawith(const P &p)const
{
return abs( (p1-p)*(p2-p)/ );
}
P vecfrom(const P &p)const
{
P v=(p2-p1);
v=v.rotate({,},pi/);
ld s1=(p1-p)*(p2-p);
ld s2=v*(p2-p1);
v=v*(s1/s2);
return v;
}
P footfrom(const P &p)const
{
P v=vecfrom(p);
return p+v;
}
ld dis1from(const P &p)const
{
P foot=footfrom(p);
if (have1(foot)) return (foot-p).length();
return min( (p1-p).length(),(p2-p).length());
}
ld dis2from(const P &p)const
{
P foot=footfrom(p);
if (have2(foot)) return (foot-p).length();
return (p1-p).length();
}
ld dis3from(const P &p)const
{
return vecfrom(p).length();
}
P symP(const P &p)const
{
P v=vecfrom(p);
return p+v*;
}
bool isct11(const LINE &L)const
{
P a1=p1,a2=p2;
P b1=L.p1,b2=L.p2;
if (sgn( max(a1.x,a2.x)-min(b1.x,b2.x) )<||
sgn( max(b1.x,b2.x)-min(a1.x,a2.x) )<||
sgn( max(a1.y,a2.y)-min(b1.y,b2.y) )<||
sgn( max(b1.y,b2.y)-min(a1.y,a2.y) )<)
return ;
lod tmp1=(a2-a1)*(b1-a1);
lod tmp2=(a2-a1)*(b2-a1);
if (sgn(tmp1)<&&sgn(tmp2)<||sgn(tmp1)>&&sgn(tmp2)>) return ;
tmp1=(b2-b1)*(a1-b1);
tmp2=(b2-b1)*(a2-b1);
if (sgn(tmp1)<&&sgn(tmp2)<||sgn(tmp1)>&&sgn(tmp2)>) return ;
return ;
}
bool isct21(const LINE &L)const
{
P v=p2-p1;
P a=p1;
P b1=L.p1,b2=L.p2;
lod tmp1=v*(b1-a);
lod tmp2=v*(b2-a);
if (sgn(tmp1)<&&sgn(tmp2)<||sgn(tmp1)>&&sgn(tmp2)>) return ;
if (tmp1>tmp2) swap(b1,b2);
if (sgn( (b1-a)*(b2-a) )>) return ;
if (sgn( (b1-a)*(b2-a) )<) return ;
return L.have1(a)||have2(b1)||have2(b2);
}
bool isct31(const LINE &L)const
{
P v=p2-p1;
P a=p1;
lod tmp1=v*(L.p1-a);
lod tmp2=v*(L.p2-a);
if (sgn(tmp1)<&&sgn(tmp2)<||sgn(tmp1)>&&sgn(tmp2)>) return ;
return ;
}
bool isct22(const LINE &L)const
{
if (have2(L.p1)||L.have2(p1)) return ;
P v=vecfrom(L.p1);
if (sgn( v%(L.p2-L.p1) )<=) return ;
v=L.vecfrom(p1);
if (sgn( v%(p2-p1) )<=) return ;
return ;
}
bool isct32(const LINE &L)const
{
if (have3(L.p1)) return ;
P v=vecfrom(L.p1);
if (sgn( v%(L.p2-L.p1) )<=) return ;
return ;
}
bool isct33(const LINE &L)const
{
if (have3(L.p1)) return ;
return sgn( (p2-p1)*(L.p2-L.p1) )!=;
}
ld dis33(const LINE &L)const
{
return (L.p1-p1)*(L.p2-p1) / ( (p2-p1)*(L.p2-L.p1) )
* (p2-p1).length();
}
P isctPoint(const LINE &L)const
{
ld len=dis33(L);
P v=p2-p1;
return p1+v*(len/v.length());
} }; const int POLNUM=;
struct PL
{
ld len;
int v;
}stk[POLNUM];
int top;
bool cmplen(const PL &a,const PL &b)
{
return a.len<b.len;
}
P cent;
bool cmpang(const P &p1,const P &p2)
{
int tmp=sgn( (p1-cent).ang() - (p2-cent).ang() );
if (tmp!=) return tmp<;
return (p1-cent).length() < (p2-cent).length();
}
struct POLYGON
{
int n;
P a[POLNUM];
void read(int k)
{
for (int i=;i<=k;i++) a[i].read();
n=k;
}
void ChangetoConvex()
{
for (int i=;i<=n;i++)
if (a[i].x<a[].x||a[i].x==a[].x&&a[i].y<a[].y)
swap(a[],a[i]);
cent=a[];
sort(a+,a+n+,cmpang);
int top=;
for (int i=;i<=n;i++)
{
while(top>=&&
sgn((a[top]-a[top-])*(a[i]-a[top]))<= )
top--;
a[++top]=a[i];
}
n=top;
}
ld Clength()const
{
ld ret=;
for (int i=;i<=n;i++) ret+=(a[i]-a[i-]).length();
if (n>) ret+=(a[]-a[n]).length();
return ret;
}
bool have(const P p)
{
int k,d1,d2,wn=;
a[]=a[n];
for (int i=;i<=n;i++)
{
LINE L={a[i-],a[i]};
if (L.have1(p)) return ;
k=sgn( (a[i]-a[i-])*(p-a[i-]) );
d1=sgn( a[i-].y-p.y );
d2=sgn( a[i].y-p.y );
if (k>&&d1<=&&d2>) wn++;
if (k<&&d2<=&&d1>) wn--;
}
return wn!=;
}
ld cutlength(const LINE &L)
{
a[]=a[n]; top=;
for (int i=;i<=n;i++)
{
LINE R={a[i-],a[i]};
lod s1=sgn( (L.p2-L.p1)*(R.p1-L.p1) );
lod s2=sgn( (L.p2-L.p1)*(R.p2-L.p1) );
if (s1<&&s2<||s1==&&s2==||s1>&&s2>) continue;
if (s1<s2) stk[++top]={L.dis33(R),(s1!=&&s2!=?:)};
else stk[++top]={L.dis33(R),(s1!=&&s2!=?-:-)};
}
sort(stk+,stk+top+,cmplen);
int cnt=;
ld ret=;
for (int i=;i<=top;i++)
{
if (cnt) ret+=stk[i].len-stk[i-].len;
cnt+=stk[i].v;
}
return ret;
}
bool isct(const POLYGON &POL)const
{
for (int i=;i<=n;i++)
for (int j=;j<=POL.n;j++)
{
LINE L1={a[i-],a[i]};
LINE L2={POL.a[j-],POL.a[j]};
if (L1.isct11(L2)) return ;
}
return ;
}
ld isctarea(const POLYGON &POL)const;
}; int T,n,f[];
P p[];
POLYGON a,b;
int init()
{
a.n=b.n=;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
p[i].read();
scanf("%d",&f[i]);
if(f[i]>)a.a[++a.n]=p[i];
else b.a[++b.n]=p[i];
}
if(a.n>b.n)swap(a,b);
if(!a.n)return printf("Successful!\n"),;
if(b.n==)
{
if((a.a[]-b.a[]).length()<eps)return printf("Infinite loop!\n"),;
return printf("Successful!\n"),;
}
b.ChangetoConvex();
for(int i=;i<=a.n;i++)
if(b.have(a.a[i]))return printf("Infinite loop!\n"),;
a.ChangetoConvex();
if(a.isct(b))return printf("Infinite loop!\n"),;
return printf("Successful!\n"),;
}
int main()
{
scanf("%d",&T);
while(T--)init();
return ;
}
05-28 00:42