题解 UVA1600 【巡逻机器人 Patrol Robot】

· · 题解

在“不能连续穿越 $k$ 个障碍”的条件下,机器人每到一个位置,如果它先前也到过这个位置但是两次连续穿越的障碍数不一样,那么机器人也是可以走到这个位置的。所以用 $vis[x][y][k]$ 表示机器人是否到过 $(x,y)$ 这个位置且连续穿越的障碍数为 $k$ ,目的 **只是为了使结果更优** 。 其他的就是普通的搜索了吧QWQ,代码: ```cpp #include <cstdio> #include <cstring> #include <queue> struct Node { int x, y, s, step; };//s为连续穿过的障碍个数 int t, m, n, k, a[23][23]; const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}; bool vis[25][25][531];//注意第三维的大小 int main() { scanf("%d", &t); while (t--) { scanf("%d%d%d", &m, &n, &k); for (int i = 1; i <= m; i++) for (int j = 1; j <= n; j++) scanf("%d", &a[i][j]); std::queue<Node> q; memset(vis, 0, sizeof vis); q.push((Node){1, 1, 0, 0}); bool ok = 0;//ok判断能否找到解 while (!q.empty()) { Node t = q.front(); q.pop(); if (t.x == m && t.y == n) {//找到解,输出 printf("%d\n", t.step); ok = 1; break;//注意是多组数据,不能直接return 0; } vis[t.x][t.y][t.s] = 1; for (int i = 0; i < 4; i++) { int tx = t.x + dx[i], ty = t.y + dy[i]; if (tx >= 1 && tx <= m && ty >= 1 && ty <= n) { if (a[tx][ty] && t.s + 1 <= k && !vis[tx][ty][t.s + 1])//这里判断的是走到(tx,ty)的情况 q.push((Node){tx, ty, t.s + 1, t.step + 1}); else if (!a[tx][ty] && !vis[tx][ty][0]) q.push((Node){tx, ty, 0, t.step + 1});//如果这个位置为空地,连续穿过的空地数显然为0 } } } if (!ok) puts("-1"); } return 0; } ```