毒瘤计算几何。。。
判断一下每一个联通块覆盖边界的情况,看看能不能把起点和终点间隔开,并查集维护一下,需要判掉在矩形外面的联通块,如果两个圆圆心连线和矩形没有交点,那么我们认为这两个圆就算有交点,也是不联通的,然后就是个码农题了。。。
代码:
#include<bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int MAXN=1005;
const double eps=1e-8;
const double PI=acos(-1.0);
int sgn(ll x)
{
if(abs(x)<eps)return 0;
if(x<0)return -1;
else return 1;
}
struct Point
{
ll x,y;
Point(){}
Point(ll _x,ll _y):x(_x),y(_y){}
Point operator - (const Point &b)const
{
return Point(x-b.x,y-b.y);
}
double operator ^ (const Point &b)const//外积
{
return x*b.y-y*b.x;
}
double operator * (const Point &b)const//内积
{
return x*b.x+y*b.y;
}
};
struct Line
{
Point s,e;
Line(){}
Line(Point _s,Point _e):s(_s),e(_e){}
};
struct Circle
{
Point o;
ll r;
int val;
Circle(){}
void input()
{
scanf("%lld%lld%lld",&o.x,&o.y,&r);
val=0;
}
}c[MAXN];
ll sqr(ll x)
{
return x*x;
}
ll dist(Point s,Point e)
{
return ((s-e)*(s-e));
}
bool inter(Circle c1,Circle c2)
{
ll d=dist(c1.o,c2.o);
return d<sqr(c1.r+c2.r);
}
bool inter(Circle c1,Point p)
{
ll d=dist(c1.o,p);
return d<sqr(c1.r);
}
bool inter(Circle c1,Line l)
{
if(inter(c1,l.s)||inter(c1,l.e))
return true;
if(l.s.x==l.e.x)
{
ll L=min(l.s.y,l.e.y);
ll R=max(l.s.y,l.e.y);
if(c1.o.y>=L&&c1.o.y<=R)
{
ll d=abs(c1.o.x-l.s.x);
if(d<c1.r) return true;
}
}
if(l.s.y==l.e.y)
{
ll L=min(l.s.x,l.e.x);
ll R=max(l.s.x,l.e.x);
if(c1.o.x>=L&&c1.o.x<=R)
{
ll d=abs(c1.o.y-l.s.y);
if(d<c1.r) return true;
}
}
return false;
}
bool inter(Line l1,Line l2)
{
return
max(l1.s.x,l1.e.x)>=min(l2.s.x,l2.e.x)&&
max(l2.s.x,l2.e.x)>=min(l1.s.x,l1.e.x)&&
max(l1.s.y,l1.e.y)>=min(l2.s.y,l2.e.y)&&
max(l2.s.y,l2.e.y)>=min(l1.s.y,l1.e.y)&&
sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e))<=0&&
sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e))<=0;
}
ll X1,X2,Y1,Y2;
int n;
bool outer(Point p)
{
if(p.x>=X1&&p.x<=X2&&p.y>=Y1&&p.y<=Y2)
return false;
return true;
}
struct DSU
{
int fa[MAXN];
void init()
{
for(int i=1;i<=n;i++)
fa[i]=i;
}
int find(int x)
{
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void Union(int x,int y)
{
x=find(x);y=find(y);
if(x==y) return ;
fa[x]=y;
}
}dsu;
vector<Line> border;
vector<int> wa;
int flag[MAXN];
void init()
{
for(int i=1;i<=n;i++) flag[i]=0;
border.clear();
dsu.init();
border.pb(Line(Point(X1,Y1),Point(X2,Y1)));
border.pb(Line(Point(X2,Y1),Point(X2,Y2)));
border.pb(Line(Point(X2,Y2),Point(X1,Y2)));
border.pb(Line(Point(X1,Y2),Point(X1,Y1)));
}
void solve()
{
for(int i=1;i<=n;i++)
{
c[i].input();
}
init();
for(int i=1;i<=n;i++)
for(int j=0;j<4;j++)
if(inter(c[i],border[j]))
c[i].val|=1<<j;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(inter(c[i],c[j]))
{
if(!outer(c[i].o)&&!outer(c[j].o))
dsu.Union(i,j);
else
{
Line cir=Line(c[i].o,c[j].o);
bool in=false;
for(int k=0;k<4;k++)
{
in|=inter(cir,border[k]);
}
if(in)
dsu.Union(i,j);
}
}
}
}
for(int i=1;i<=n;i++)
{
int fa=dsu.find(i);
flag[fa]|=c[i].val;
}
for(int i=1;i<=n;i++)
{
int fa=dsu.find(i);
if(i!=fa) continue;
for(int j=0;j<4;j++)
{
if((wa[j]&flag[i])==wa[j])
{
puts("NO");
return ;
}
}
}
puts("YES");
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
wa.pb(5);wa.pb(9);wa.pb(10);wa.pb(6);
while(~scanf("%lld%lld%lld%lld%d",&X1,&Y1,&X2,&Y2,&n))
{
solve();
}
return 0;
}