POJ - 1556 The Doors (shortest line segment intersects +)

Topic links: Click here

Subject to the effect: given a room, there are a lot of walls (up to 18 walls) in the room, and now from (0,5) to the point (10,5) points, ask how much is the shortest distance

Topic Analysis: To make the shortest distance, it must move forward between two points, and we built the wall after, according to the gradient line segment intersection problem, determine whether the line blocked off between two points, if not blocked, direct direct construction side, the right side is the straight line distance between two points, if blocked, that is, there is a line segment specification and the current intersection, then the two can not be reached directly, the right side is set to infinity, built after the edge shortest run is the answer, because the value is small, with a relatively simple Floyd

Code:

#include<iostream>
#include<cstdio> 
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
 
typedef long long LL;
 
const int inf=0x3f3f3f3f;

const int N=110;

const double eps = 1e-8;

int sgn(double x){
	if(fabs(x) < eps)return 0;
	if(x < 0)return -1;
	else return 1;
}

struct Point{
	double x,y;
	Point(){}
	Point(double _x,double _y){
		x = _x;
		y = _y;
	}
	void input(){
		scanf("%lf%lf",&x,&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;
	}
	//返回两点的距离
	double distance(Point p){
		return hypot(x-p.x,y-p.y);
	}
};

struct Line{
	Point s,e;
	Line(){}
	Line(Point _s,Point _e){
		s = _s;
		e = _e;
	}
	//`两线段相交判断`
	//`2 规范相交`
	//`1 非规范相交`
	//`0 不相交`
	int segcrossseg(Line v){
		int d1 = sgn((e-s)^(v.s-s));
		int d2 = sgn((e-s)^(v.e-s));
		int d3 = sgn((v.e-v.s)^(s-v.s));
		int d4 = sgn((v.e-v.s)^(e-v.s));
		if( (d1^d2)==-2 && (d3^d4)==-2 )return 2;
		return (d1==0 && sgn((v.s-s)*(v.s-e))<=0) ||
			(d2==0 && sgn((v.e-s)*(v.e-e))<=0) ||
			(d3==0 && sgn((s-v.s)*(s-v.e))<=0) ||
			(d4==0 && sgn((e-v.s)*(e-v.e))<=0);
	}
};

vector<Line>line;

vector<Point>point;

double maze[N][N];

bool check(Line l)
{
	if(sgn(l.s.distance(l.e))==0)
		return true;
	for(int i=0;i<line.size();i++)
	{
		if(line[i].segcrossseg(l)==2)
			return false;
	}
	return true;
}

void init()
{
	for(int i=0;i<N;i++)
		for(int j=0;j<N;j++)
			maze[i][j]=1e10;
	line.clear();
	point.clear();
	point.push_back(Point(0,5));
	point.push_back(Point(10,5));
}

int main()
{
//	freopen("input.txt","r",stdin);
//	ios::sync_with_stdio(false);
	int n;
	while(scanf("%d",&n)!=EOF&&n!=-1)
	{
		init();
		for(int i=1;i<=n;i++)
		{
			double x,y[4];
			scanf("%lf",&x);
			for(int j=0;j<4;j++)
			{
				scanf("%lf",y+j);
				point.push_back(Point(x,y[j]));
			}
			line.push_back(Line(Point(x,0),Point(x,y[0])));
			line.push_back(Line(Point(x,y[1]),Point(x,y[2])));
			line.push_back(Line(Point(x,y[3]),Point(x,10)));
		}
		for(int i=0;i<point.size();i++)
			for(int j=i;j<point.size();j++)
			{
				if(check(Line(point[i],point[j])))
					maze[i][j]=maze[j][i]=point[i].distance(point[j]);
				else
					maze[i][j]=1e10;
			}
		for(int k=0;k<point.size();k++)
			for(int i=0;i<point.size();i++)
				for(int j=0;j<point.size();j++)
					maze[i][j]=min(maze[i][j],maze[i][k]+maze[k][j]);
		printf("%.2f\n",maze[0][1]);
	}
	
	
 
 
 
 
 
 
 
	
	
	
	
	
	
	
	
	
	return 0;
}

 

Published 577 original articles · won praise 18 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_45458915/article/details/104093746