大意:在一个矩形区域内。有n条线段,线段的端点是在矩形边上的,有一个特殊点,问从这个点到矩形边的最少经过的线段条数最少的书目,穿越仅仅能在中点穿越。
思路:须要巧妙的转换一下这个问题,由于从一个点到终点不可能“绕过”围墙。仅仅能穿过去,所以门是否开在中点是无所谓的,仅仅要求四周线段中点到终点的线段与墙的最少交点个数就可以。更进一步,实际上,仅仅需推断四周围墙的全部点与终点的连线与内墙的最少交点加一就可以。
struct Point{ double x, y; } A, B, P[65], aim; struct Line{ Point a, b; } L[35]; int n; double xmult(Point p1, Point p2, Point p) { return (p1.x-p.x)*(p2.y-p.y)-(p2.x-p.x)*(p1.y-p.y); } bool Intersection(Line u, Line v) { return (max(u.a.x, u.b.x) >= min(v.a.x, v.b.x)) && (max(v.a.x, v.b.x) >= min(u.a.x, u.b.x)) && (max(u.a.y, u.b.y) >= min(v.a.y, v.b.y)) && (max(v.a.y, v.b.y) >= min(u.a.y, u.b.y)) && (xmult(u.a, v.a, u.b)*xmult(u.a, u.b, v.b) > eps) && (xmult(v.a, u.a, v.b)*xmult(v.a, v.b, u.b) > eps); } void Solve() { scanf("%d", &n); int t = 0; for(int i = 0; i < n; ++i) { scanf("%lf%lf%lf%lf", &A.x, &A.y, &B.x, &B.y); P[t++] = L[i].a = A; P[t++] = L[i].b = B; } scanf("%lf%lf", &aim.x, &aim.y); int ans = INF; for(int i = 0; i < t; ++i) { int cnt = 0; Line p = (Line){aim, P[i]}; for(int j = 0; j < n; ++j) { if(Intersection(p, L[j])) { cnt++; } } if(cnt < ans) { ans = cnt; } } printf("Number of doors = %d ", n?ans+1:1); }
版权声明:本文博主原创文章,博客,未经同意不得转载。