题目大意:有一个房间(左上角(0,10),右下角(10,0)),然后房间里有N面墙,每面墙上都有两个门,求出来从初始点(0,5),到达终点(10,5)的最短距离。
分析:很明显根据两点之间直线最短,所以所走的路线一定是点之间的连线,只需要判断一下这两点间知否有墙即可。
代码如下:
======================================================================================================================================
#include<math.h> #include<algorithm> #include<stdio.h> using namespace std; const int MAXN = 1007; const double oo = 1e9+7; const double EPS = 1e-8; struct point { double x, y, len; point(double x=0, double y=0, double len=0):x(x),y(y),len(len){} point operator - (const point &t) const{ return point(x-t.x, y-t.y); } int operator *(const point &t) const{ double c = x*t.y - y*t.x; if(c > EPS)return 1; if(fabs(c)<EPS)return 0; return -1; } }; struct Wall { point A, B; Wall(point A=0, point B=0):A(A), B(B){} }; bool CanLine(point a, point b, Wall w[], int N) { for(int i=0; i<N; i++) { if( w[i].A.x < b.x || w[i].A.x > a.x ) continue; int t = (a-b)*(w[i].A-b) + (a-b)*(w[i].B-b); if(t == 0) return false; } return true; } int main() { int M; while(scanf("%d", &M) != EOF && M != -1) { int i, j, nw=0, np=1; double x, y[10]; Wall w[MAXN]; point p[MAXN]; p[0] = point(0, 5, 0); while(M--) { scanf("%lf%lf%lf%lf%lf", &x, &y[0], &y[1], &y[2], &y[3]); p[np++] = point(x, y[0], oo), p[np++] = point(x, y[1], oo); p[np++] = point(x, y[2], oo), p[np++] = point(x, y[3], oo); w[nw++] = Wall(point(x, -1), point(x, y[0])); w[nw++] = Wall(point(x, y[1]), point(x, y[2])); w[nw++] = Wall(point(x, y[3]), point(x, 11)); } p[np++] = point(10, 5, oo); for(i=1; i<np; i++) for(j=0; j<i; j++) { point t = p[i] - p[j]; t.len = sqrt(t.x*t.x+t.y*t.y); if(p[i].len > t.len + p[j].len && CanLine(p[i], p[j], w, nw) == true) p[i].len = t.len + p[j].len; } printf("%.2f ", p[np-1].len); } return 0; }