题目:https://vjudge.net/problem/UVALive-2797
把直线的每两个端点点处理一遍,因为只有贴着端点才能过。
若遇到直线端点相交情况,把每条线段稍微延长一点,通过判断是否相交即可判断是否可以通过
#include<bits/stdc++.h>
using namespace std;
struct Point{
double x,y;
Point(double x=0,double y=0) :x(x),y(y){}
};
int n;
typedef Point Vector;
Vector operator +(Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
Vector operator -(Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}
Vector operator *(Vector A,double p){return Vector(A.x*p,A.y*p);}
Vector operator /(Vector A,double p){return Vector(A.x/p,A.y/p);}
bool operator <(const Point& a,const Point &b){
return a.x<b.x || (a.x==b.x && a.y<b.y);
}
const double eps=1e-10;
int dcmp(double x){
if(fabs(x)<eps) return 0;else return x<0?-1 :1;
}
bool operator == (const Point &a,const Point &b){
return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;}
double dot(Vector A,Vector B){
return A.x*B.x+A.y*B.y;
}
double length(Vector A){return sqrt(dot(A,A));}
double angle(Vector A,Vector B){
return acos(dot(A,B)/length(A)/length(B));
}
Vector rotate(Vector A,double rad){ //rad正数时表示逆时针 负数时表示顺时针
return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
//计算向量的单位法线
Vector normal(Vector A){
double l=length(A);
return Vector(-A.y/l,A.x/l);
}
double cross(Vector A,Vector B){
return A.x*B.y-A.y*B.x;
}
struct Line{
Point p;
Vector v;
Line(Point p,Vector v):p(p),v(v){}
Point point(double t){return p+v*t;}
};
bool segmenproperintersection(Point a1,Point a2,Point b1,Point b2){
double c1=cross(a2-a1,b1-a1),c2=cross(a2-a1,b2-a1),
c3=cross(b2-b1,a1-b1),c4=cross(b2-b1,a2-b1);
return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}
bool onsegment(Point p,Point a1,Point a2){
return dcmp(cross(a1-p,a2-p))==0 && dcmp(dot(a1-p,a2-p))<0;
}
Point p1[105],p2[105];
bool onanysegment(Point p){
for(int i=0;i<n;i++)
if(onsegment(p,p1[i],p2[i]))
return true;
return false;
}
bool interanysection(Point a,Point b){
for(int i=0;i<n;i++)
if(segmenproperintersection(a,b,p1[i],p2[i]))
return true;
return false;
}
int dis[210][210];
int vis[210];
void init(){
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
}
int dfs(int x){
if(x==1) return 1;
vis[x]=1;
for(int i=0;i<205;i++){
if(dis[x][i] && !vis[i] && dfs(i)) return 1;
}
return 0;
}
bool judge(){
vector<Point> v;
v.push_back(Point(0,0));
v.push_back(Point(1e5,1e5));
for(int i=0;i<n;i++){
if(!onanysegment(p1[i])) v.push_back(p1[i]);
if(!onanysegment(p2[i])) v.push_back(p2[i]);
}
int sz=v.size();
for(int i=0;i<sz;i++)
for(int j=i+1;j<sz;j++)
if(!interanysection(v[i],v[j])){
dis[i][j]=1;
dis[j][i]=1;
}
return dfs(0);
}
int main(){
Point a,b;
double f=1e-6;
while(scanf("%d",&n) && n){
init();
for(int i=0;i<n;i++)
{
scanf("%lf %lf",&a.x,&a.y);
scanf("%lf %lf",&b.x,&b.y);
Vector v=b-a;
v=v/length(v);
p1[i]=a-v*f;
p2[i]=b+v*f;
}
if(judge()) cout<<"no"<<endl;
else
cout<<"yes"<<endl;
}
return 0;
}