//以下为原blog搬迁过来的内容
【题目大意】:给出一个10*10的平面,对于平面上的每一个竖的截线都可能会有3面墙,题目会给出墙的端点坐标。然后要求求出(0,5)到(10,5)不穿过墙的最短路。
【解题思路】:枚举两个点,连接成线段,判断有木有墙与这题线段相交,如果没有的话,就可以前进。数据量比较小,求出所有直达的点后跑一次floyed就好了。
【代码】:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <string> #include <cctype> #include <map> #include <iomanip> using namespace std; #define eps 1e-8 #define pi acos(-1.0) #define inf 1<<30 #define pb push_back #define lc(x) (x << 1) #define rc(x) (x << 1 | 1) #define lowbit(x) (x & (-x)) #define ll long long #define INF 100000 struct Point { double x,y; Point() {} Point(double a,double b) { x=a,y=b; } }point[100][100],point1[100]; struct Line { Point a,b; Line() {} Line(Point x,Point y) { a=x,b=y; } }line[10000]; double dis[100][100]; int n,cnt1,cnt2,cnt; double p,q; inline int sig(double k) { return k < -eps ? -1 : k > eps; } inline double det(double x1, double y1, double x2, double y2) { return x1 * y2 - x2 * y1; } inline double xmult(Point o, Point a, Point b) { return det(a.x - o.x, a.y - o.y, b.x - o.x, b.y - o.y); } inline int intersect1(Point a, Point b, Point c, Point d) { double s1, s2, s3, s4; int d1 = sig(s1 = xmult(a, b, c)); int d2 = sig(s2 = xmult(a, b, d)); int d3 = sig(s3 = xmult(c, d, a)); int d4 = sig(s4 = xmult(c, d, b)); if ((d1^d2) == -2 && (d3^d4) == -2) { return 1; } return 0; } inline int intersect(Line u, Line v) { return intersect1(u.a, u.b, v.a, v.b); } inline double getDist(Point a, Point b) { return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } int main() { while (~scanf("%d",&n)) { if (n==-1) break; point1[0]=Point(0,5); cnt1=1; cnt2=0; for (int i=0; i<=n-1; i++) { scanf("%lf",&p); cnt=0; point[i][cnt]=Point(p,0); cnt++; for (int j=1; j<=4; j++) { scanf("%lf",&q); point[i][cnt]=Point(p,q); point1[cnt1]=Point(p,q); cnt1++; cnt++; } point[i][cnt]=Point(p,10); cnt++; line[cnt2]=Line(point[i][0],point[i][1]); cnt2++; line[cnt2]=Line(point[i][2],point[i][3]); cnt2++; line[cnt2]=Line(point[i][4],point[i][5]); cnt2++; } /* for (int i=0; i<cnt2; i++) { cout << line[i].a.x << " " << line[i].a.y << " " << line[i].b.x<< " " <<line[i].b.y<<endl; }*/ point1[cnt1]=Point(10,5); cnt1++; for (int i=0; i<cnt1; i++) for (int j=0; j<cnt1; j++) dis[i][j]=INF; bool flag; for (int i=0; i<cnt1; i++) { for (int j=i+1; j<cnt1; j++) { Line tmp; tmp=Line(point1[i],point1[j]); flag=true; for (int l=0; l<cnt2; l++) { int k; k=intersect(tmp,line[l]); if (k!=0) {flag=false; break;} } if (flag==true) { dis[i][j]=getDist(point1[i],point1[j]); } } } for (int k=0;k<cnt1;k++) for (int i=0;i<cnt1;i++) if (dis[i][k] < INF) for (int j=0;j<cnt1;j++) if (dis[k][j] < INF) dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); printf("%.2lf\n",dis[0][cnt1-1]); } return 0; }