Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 5704 | Accepted: 2302 |
Description
Input
Output
Sample Input
1 5 4 6 7 8 2 4 2 7 8 9 7 3 4.5 6 7 -1
Sample Output
10.00 10.06
Source
一个最短路,但是需要判断和门是否相交,当然用dp也是可以的,只不过懒得想方程而已。
#include <stdio.h> #include <math.h> #include <string.h> #include <algorithm> using namespace std; #define INF 9999999 #define eps 1e-6 struct Wall { double col; double row[5]; }; struct Point { double x,y; }; struct Line { Point begin,end; }; Wall wall[10005]; Line line[10005]; Point point[100005]; double map[1005][1005]; int lineNum,pointNum; Line setLine(double x1,double y1,double x2,double y2) { Line ret; ret.begin.x=x1; ret.begin.y=y1; ret.end.x=x2; ret.end.y=y2; return ret; } Point setPoint(double x,double y) { Point ret; ret.x=x; ret.y=y; return ret; } double Dist(Point p,Point q) { return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y)); } double Mul(Line p,Line q) { return (p.end.x-p.begin.x)*(q.end.y-q.begin.y)-(p.end.y-p.begin.y)*(q.end.x-q.begin.x); } bool Cross(Line p,Line q) { if (min(p.begin.x,p.end.x)-max(q.begin.x,q.end.x)>eps) return false; if (min(q.begin.x,q.end.x)-max(p.begin.x,p.end.x)>eps) return false; if (min(p.begin.y,p.end.y)-max(q.begin.y,q.end.y)>eps) return false; if (min(q.begin.y,q.end.y)-max(p.begin.y,p.end.y)>eps) return false; Line line1=setLine(p.begin.x,p.begin.y,q.begin.x,q.begin.y); Line line2=setLine(p.begin.x,p.begin.y,q.end.x,q.end.y); if (Mul(p,line1)*Mul(p,line2)>-eps) return false; Line line3=setLine(q.begin.x,q.begin.y,p.begin.x,p.begin.y); Line line4=setLine(q.begin.x,q.begin.y,p.end.x,p.end.y); if (Mul(q,line3)*Mul(q,line4)>-eps) return false; return true; } double Dijkstra(int s,int t) { int vis[1005]; double d[1005]; int i,j; memset(vis,0,sizeof(vis)); for (i=0;i<pointNum;i++) { d[i]=map[s][i]; } for (i=0;i<pointNum;i++) { int idx=-1; double s=INF; for (j=0;j<pointNum;j++) { if (vis[j]==1) continue; if (s>d[j]) { idx=j; s=d[j]; } } if (idx==t) return s; vis[idx]=1; for (j=0;j<pointNum;j++) { d[j]=min(d[j],d[idx]+map[idx][j]); } } } int main() { int i,j,n,k; while(1) { scanf("%d",&n); if (n==-1) break; lineNum=pointNum=0; point[pointNum++]=setPoint(0,5); point[pointNum++]=setPoint(10,5); for (i=0;i<n;i++) { scanf("%lf",&wall[i].col); for (j=0;j<4;j++) { scanf("%lf",&wall[i].row[j]); point[pointNum++]=setPoint(wall[i].col,wall[i].row[j]); } line[lineNum++]=setLine(wall[i].col,0,wall[i].col,wall[i].row[0]); line[lineNum++]=setLine(wall[i].col,wall[i].row[1],wall[i].col,wall[i].row[2]); line[lineNum++]=setLine(wall[i].col,wall[i].row[3],wall[i].col,10); } for (i=0;i<pointNum;i++) { map[i][i]=0; for (j=i+1;j<pointNum;j++) { for (k=0;k<lineNum;k++) { Line tmp=setLine(point[i].x,point[i].y,point[j].x,point[j].y); if (Cross(tmp,line[k])==true) break; } if (k==lineNum) map[i][j]=map[j][i]=Dist(point[i],point[j]); else map[i][j]=map[j][i]=INF; } } printf("%.2f\n",Dijkstra(0,1)); } return 0; }