LA 2797 怪物陷阱(平面直線PSLG)

題目: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;
		
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章