Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 7392 | Accepted: 2900 |
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 题意:有n堵墙,每个墙上有两个门,给你墙的x坐标和门的Y坐标,求从(0,5)到(10,5)的最短距离 思路:看了之后秒想到最短路,刚开始没看到一个墙上只有两个门,想了很久,后来看到了就直接写了,在输入的时 候记录每条线段和每个点,并记录他们属于哪个墙,然后求出两个点两个点组成线段是否与其他的线段相交,如果不 相交,记录距离,最后dijkstra一下就行了。。。(PS:注意边界墙号的赋值,这点我坑了一个小时 = = 衰) ac代码:#include<stdio.h> #include<math.h> #include<string.h> #include<stack> #include<queue> #include<map> #include<vector> #define MAXN 1000 #define LL long long #define INF 0xfffffff*1.0 #define mem(x) memset(x,0,sizeof(x)) #define PI acos(-1) #include<iostream> #include<algorithm> using namespace std; struct s { double x,y; int num; }list[MAXN]; struct ss { double x1,x2,y1,y2; int k; }line[MAXN]; double pri[MAXN][MAXN]; double D[MAXN]; int v[MAXN]; int cnt,cnt2; double dis(s a,s b) { return sqrt(1.0*((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))); } double fun(ss aa,double xx,double yy) { return (aa.x2-aa.x1)*(yy-aa.y1)-(xx-aa.x1)*(aa.y2-aa.y1); } int check(ss A,ss B) { if(max(A.x1,A.x2)<min(B.x1,B.x2)) return 0; if(max(B.x1,B.x2)<min(A.x1,A.x2)) return 0; if(max(A.y1,A.y2)<min(B.y1,B.y2)) return 0; if(max(B.y1,B.y2)<min(A.y1,A.y2)) return 0; if(fun(B,A.x1,A.y1)*fun(B,A.x2,A.y2)>1e-10) return 0; if(fun(A,B.x1,B.y1)*fun(A,B.x2,B.y2)>1e-10) return 0; return 1; } void dijkstra() { double M; int k,i,j; mem(v); for(i=0;i<=cnt;i++) D[i]=pri[0][i]; v[0]=1; for(i=0;i<cnt;i++) { M=INF; for(j=0;j<=cnt;j++) { if(!v[j]&&D[j]<M) { M=D[j]; k=j; } } if(M==INF) break; v[k]=1; for(j=0;j<=cnt;j++) { if(D[j]>D[k]+pri[k][j]) D[j]=D[k]+pri[k][j]; } } printf("%.2lf\n",D[cnt]); } int main() { int n,i,j,q; double p,y1,y2,y3,y4; while(scanf("%d",&n)!=EOF) { if(n==-1) break; cnt=1; cnt2=0; list[0].x=0.0;list[0].y=5.0;list[0].num=0;//边界墙号赋值 for(i=1;i<=n;i++) { scanf("%lf%lf%lf%lf%lf",&p,&y1,&y2,&y3,&y4); line[cnt2].x1=p;line[cnt2].y1=0;line[cnt2].x2=p;line[cnt2].k=i;line[cnt2++].y2=y1; line[cnt2].x1=p;line[cnt2].y1=y2;line[cnt2].x2=p;line[cnt2].k=i;line[cnt2++].y2=y3; line[cnt2].x1=p;line[cnt2].y1=y4;line[cnt2].x2=p;line[cnt2].k=i;line[cnt2++].y2=10.0; list[cnt].x=p;list[cnt].y=y1,list[cnt++].num=i;list[cnt].x=p;list[cnt].y=y2,list[cnt++].num=i; list[cnt].x=p;list[cnt].y=y3,list[cnt++].num=i;list[cnt].x=p;list[cnt].y=y4,list[cnt++].num=i; } list[cnt].x=10.0;list[cnt].y=5.0;list[cnt].num=n+1;//边界墙号赋值 for(i=0;i<=cnt;i++) for(j=i+1;j<=cnt;j++) pri[i][j]=pri[j][i]=INF; for(i=0;i<=cnt;i++) { ss a,b; a.x1=list[i].x;a.y1=list[i].y; for(j=i+1;j<=cnt;j++) { if(list[i].num==list[j].num) continue; a.x2=list[j].x;a.y2=list[j].y; int bz=0; for(q=0;q<cnt2;q++) { if(line[q].k==list[i].num||line[q].k==list[j].num) continue; if(check(a,line[q])) { bz=1; break; } } if(bz==0) pri[i][j]=pri[j][i]=dis(list[i],list[j]); } } dijkstra(); } return 0; }