首页 > 代码库 > POJ 1066 Treasure Hunt(线段相交&&转换)
POJ 1066 Treasure Hunt(线段相交&&转换)
Treasure Hunt
大意:在一个矩形区域内,有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", n?ans+1:1); }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。