题意:有一条河,河中有n个石头,给出了河的宽度和石头的位置,一个人要渡河,给出了这个人最远跳多远。问最少跳几下跳到对岸,或者如果跳不到那么就输出可以离对岸最近的距离。
题解:bfs,直接暴力把所有可能跳的情况都过一遍就可以找到解了。
#include <cstdio> #include <cmath> #include <algorithm> #include <queue> using namespace std; const int N = 1005; struct P { int x, y, step, id; }p[N]; int yy, n; double d; queue<P> q; bool cmp(P a, P b) { if (a.y != b.y) return a.y < b.y; return a.x < b.x; } double dist(P a, P b) { if (b.id != n + 1) return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); return fabs(b.y - a.y); } int bfs() { p[0].step = 0; int res = 0x3f3f3f3f, minn = 0; for (int i = 1; i <= n + 1; i++) { if (p[i].y <= d) { p[i].step = 1; if (i == n + 1) return 1; q.push(p[i]); } else break; } while (!q.empty()) { P u = q.front(); q.pop(); minn = max(minn, u.y); for (int i = u.id + 1; i <= n + 1; i++) { if (dist(u, p[i]) - d <= 1e-7 && p[i].step > u.step + 1) { p[i].step = u.step + 1; if (i == n + 1) break; q.push(p[i]); } if (fabs(u.y - p[i].y) > d)//剪枝 break; } } if (p[n + 1].step == 0x3f3f3f3f) return minn - yy; return p[n + 1].step; } int main() { int t; scanf("%d", &t); while (t--) { while (!q.empty()) q.pop(); scanf("%d%d%lf", &yy, &n, &d); for (int i = 1; i <= n; i++) { scanf("%d%d", &p[i].x, &p[i].y); p[i].step = 0x3f3f3f3f; } sort(p + 1, p + 1 + n, cmp); p[0].y = 0; p[n + 1].y = yy; p[n + 1].step = 0x3f3f3f3f; for (int i = 0; i <= n + 1; i++) p[i].id = i; int res = bfs(); if (res > 0) printf("YES\n%d\n", res); else printf("NO\n%d\n", -res); } return 0; }
原文:http://blog.csdn.net/hyczms/article/details/45076653