本题通过主要是要明白最短路径必定是通过门边产生的如图
如上图,不会残生第三种情况,所以这道题就简单了,先求任意两直接可连线点间的距离,再通过dijkstra算法求出最短路即可。
两直接可连线点是指两线段可以之间连线,并且不存在其他线段在两点之间(可以端点相交)。两线段是否相交可以通过快速排斥实验和跨立实验完成,然后细心一点就好了。#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#define INF 0x3f3f3f3f
#define max_dou 10000000;
using namespace std;
struct node{
double x;
double y1,y2,y3,y4;
};
struct point{
double x,y;
};
point pt[75];
node wall[20];//代表每堵墙
double mp[18*4+2+1][75];
double d[75];
bool used[75];
int V;
void dijkstra(int s){
fill(d+1,d+V+1,INF);
fill(used+1,used+V+1,false);
d[s]=0;
while(true){
int v=-1;
for(int u=1;u<=V;u++){
if(!used[u]&&(v==-1||d[u]<d[v])) v=u;
}
if(v==-1) break;
used[v]=true;
for(int u=1;u<=V;u++){
d[u]=min(d[u],d[v]+mp[u][v]);
}
}
}
int pc(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4){
if(min(x1,x2)<=max(x3,x4)&&min(x3,x4)<=max(x1,x2)
&&min(y1,y2)<=max(y3,y4)&&min(y3,y4)<=max(y1,y2))
return 1;//不排斥
else return 0;
}
int judge(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4){
if(((x1-x3)*(y4-y3)-(x4-x3)*(y1-y3))*((x4-x3)*(y2-y3)-(x2-x3)*(y4-y3))>0&&
((x3-x2)*(y1-y2)-(x1-x2)*(y3-y2))*((x1-x2)*(y4-y2)-(y1-y2)*(x4-x2))>0&&
pc(x1,y1,x2,y2,x3,y3,x4,y4))
return 0;//两线段相交
else return 1;//两线段不相交
}
int main()
{
int n;
while(cin>>n&&n!=-1){
V=4*n+2;
memset(mp,INF,sizeof(mp));
for(int i=0;i<=74;i++){
for(int j=0;j<=74;j++){
mp[i][j]=max_dou;
}
}
for(int i=1;i<=n;i++){
cin>>wall[i].x>>wall[i].y1>>wall[i].y2>>wall[i].y3>>wall[i].y4;
}
for(int i=0;i<n;i++){
pt[4*i+2].x=wall[i+1].x,pt[4*i+2].y=wall[i+1].y1;
pt[4*i+3].x=wall[i+1].x,pt[4*i+3].y=wall[i+1].y2;
pt[4*i+4].x=wall[i+1].x,pt[4*i+4].y=wall[i+1].y3;
pt[4*i+5].x=wall[i+1].x,pt[4*i+5].y=wall[i+1].y4;
}
pt[1].x=0,pt[1].y=5;
pt[4*n+2].x=10,pt[4*n+2].y=5;
for(int i=1;i<=4*n+2;i++){
for(int j=i+1;j<=4*n+2;j++) {
int d=0;
for(int k=1;k<=n;k++){
if(judge(pt[i].x,pt[i].y,pt[j].x,pt[j].y,wall[k].x,0,wall[k].x,wall[k].y1)&&
judge(pt[i].x,pt[i].y,pt[j].x,pt[j].y,wall[k].x,wall[k].y2,wall[k].x,wall[k].y3)&&
judge(pt[i].x,pt[i].y,pt[j].x,pt[j].y,wall[k].x,wall[k].y4,wall[k].x,10)){
d++;
}
}
if(d==n){
mp[i][j]=sqrt((pt[i].x-pt[j].x)*(pt[i].x-pt[j].x)+(pt[i].y-pt[j].y)*(pt[i].y-pt[j].y));
mp[j][i]=mp[i][j];
}
}
}
dijkstra(1);
printf("%.2lf\n",d[4*n+2]);
}
return 0;
}