POJ 1556 The Doors 点与线段交+最短路

5 篇文章 0 订阅
4 篇文章 0 订阅
该博客探讨了POJ 1556题目,涉及计算几何中的线段交点判断及Floyd算法求最短路问题。文章指出,尽管数据范围较小,但通过暴力求解与Floyd算法的结合,可以找到从房间左边中点到右边中点的最短路径。
摘要由CSDN通过智能技术生成

题目链接:http://poj.org/problem?id=1556


题目大意:一个房间里有很多墙,每道墙上有两个门,求从房间左边中点到右边中点的最短距离。如图:

 


这道题目说起来就是一道最短路的题,但是两点之间是否能够走,需要判断一下两点之间的连线是不是跟墙有交点,就是计算几何的判断线段相交问题。两类典型的题合在一起了。

由于数据范围小的可怜,无脑暴力+floyd都能够过= =

 

AC代码:


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#define MAXN 50
#define INF 1000000
using namespace std;

struct Point
{
	double x,y;
	Point(double x=0,double y=0):x(x),y(y){}
};

typedef Point Vector;

Vector operator + (Vector A,Vector B) {return Vector(A.x+B.x,A.y+B.y);}
Vector operator - (Point A,Point 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);}

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 Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;}

struct Line
{
	Point P;
	Vector v; 
};

double GetLineIntersection(Line A,Line B) //返回交点相对P的t值 
{
	Point P=A.P,Q=B.P;
	Vector v=A.v,w=B.v;
	Vector u=P-Q;
	double t=Cross(w,u) / Cross(v,w);
	return t;
}

//以上是计算几何基本内容 


int n;
Point points[4*MAXN];//记录点 
double dis[4*MAXN][4*MAXN];//记录距离 
Line lines[MAXN][3];//记录线段 

int main()
{
	Line l;
	Vector v,w;
	Point a,b;
	double x,t,t2;
	int i,j,k,o,mark;
	
	while(cin>>n)
	{
		if(n==-1) break;
		//初始化起点终点 
		points[n*4].x=0;
		points[n*4+1].x=10;
		points[n*4].y=points[n*4+1].y=5;
		
		for(i=0;i<n;i++)
		{
			cin>>x>>points[i*4+0].y>>points[i*4+1].y>>points[i*4+2].y>>points[i*4+3].y;
			a.x=b.x=points[i*4+0].x=points[i*4+1].x=points[i*4+2].x=points[i*4+3].x=x;
			a.y=0;b.y=10;
			
			//每道墙3条线  a-0 1-2 3-b 
			lines[i][0].P=a;
			lines[i][0].v=points[i*4+0]-a;
			lines[i][1].P=points[i*4+1];
			lines[i][1].v=points[i*4+2]-points[i*4+1];
			lines[i][2].P=points[i*4+3];
			lines[i][2].v=b-points[i*4+3];
		}
		
		//设置距离初始值 
		for(i=0;i<4*n+2;i++)
		for(j=0;j<=i;j++)
			dis[i][j]=dis[j][i]=INF;
		
		//枚举两两点对 
		for(i=0;i<4*n+2;i++)
		for(j=0;j<i;j++)
		{
			if(points[i].x==points[j].x) continue;
			v=points[i]-points[j];
			//给两点之间连线段赋值 
			l.P=points[j];
			l.v=v;
			mark=0;//标记 
			
			//枚举所有的线段 
			for(k=0;k<n;k++)
			for(o=0;o<3;o++)
			{
				if(mark) break;
				t=GetLineIntersection(l,lines[k][o]);
				t2=GetLineIntersection(lines[k][o],l);
				if(t>0&&t<1&&t2>0&&t2<1)//如果交点在线段上,不能连 
				{
					mark=1;
					break;
				}
			}
			if(mark==0) dis[i][j]=dis[j][i]=Length(l.v);//可以连,更新距离 
		}
		
		//floyd跑最短路 
		for(k=0;k<4*n+2;k++)
		for(i=0;i<4*n+2;i++)
		for(j=0;j<4*n+2;j++)
			dis[i][j]=dis[i][j]<dis[i][k]+dis[k][j]?dis[i][j]:dis[i][k]+dis[k][j];
		
		printf("%0.2f\n",dis[n*4+1][n*4+0]);
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值