题意:给出一个房间的俯视图 求从(0,5)到(10,5)的最短路径。
求出没有墙挡住的两点距离再用弗洛伊德求出0-sum的最短路径就可以。需要注意最短路可能经过某墙的端点,这时候不能判断条路径为非法。
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef double PointType; #define oo 999999 struct point { PointType x,y; }; PointType Direction(point pi,point pj,point pk) //判断向量PiPj在向量PiPk的顺逆时针方向 +顺-逆0共线 { return (pj.x-pi.x)*(pk.y-pi.y)-(pk.x-pi.x)*(pj.y-pi.y); } bool On_Segment(point pi,point pj,point pk) { if(pk.x>=min(pi.x,pj.x)&&pk.x<=max(pi.x,pj.x)&&pk.y>=min(pi.y,pj.y)&&pk.y<=max(pi.y,pj.y)) return 1; return 0; } bool Segment_Intersect(point p1,point p2,point p3,point p4) { PointType d1=Direction(p3,p4,p1),d2=Direction(p3,p4,p2),d3=Direction(p1,p2,p3),d4=Direction(p1,p2,p4); if(((d1>0&&d2<0)||(d1<0&&d2>0))&&((d3>0&&d4<0)||(d3<0&&d4>0))) return 1; return 0; } double dis(point a,point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double dist[100][100]; bool judge(point a,point b,point c) { if(a.x!=c.x&&b.x!=c.x) return 1; return 0; } int main() { int n; point data[80],edge[18][6]; while(~scanf("%d",&n),n!=-1) { for(int i=0; i<100; i++) for(int j=0; j<100; j++) dist[i][j]=oo; int sum=1; double w[4],x; for(int i=0; i<n; i++) { scanf("%lf%lf%lf%lf%lf",&x,&w[0],&w[1],&w[2],&w[3]); for(int j=0; j<4; j++) { data[sum+j].x=x,data[sum+j].y=w[j]; edge[i][1+j].x=x,edge[i][1+j].y=w[j]; } edge[i][0].x=x,edge[i][0].y=0; edge[i][5].x=x,edge[i][5].y=10; sum+=4; } data[0].x=0,data[0].y=5; data[sum].x=10,data[sum].y=5; for(int i=0; i<=sum; i++) for(int j=0; j<=sum; j++) { if(data[i].x==data[j].x) continue; int flag=1; for(int k=0; k<n; k++) { if(!judge(data[i],data[j],edge[k][0])) continue; bool a1=Segment_Intersect(data[i],data[j],edge[k][0],edge[k][1]), a2=Segment_Intersect(data[i],data[j],edge[k][2],edge[k][3]), a3=Segment_Intersect(data[i],data[j],edge[k][4],edge[k][5]); if(a1||a2||a3) { flag=0; break; } } if(flag) dist[i][j]=dis(data[i],data[j]); } for(int k=0; k<=sum; ++k) for(int i=0; i<=sum; ++i) for(int j=0; j<=sum; ++j) if(dist[i][k]+dist[k][j]<dist[i][j]) dist[i][j]=dist[i][k]+dist[k][j]; printf("%.2f\n",dist[0][sum]); } return 0; }