HDU5040- Instrusive(BFS+记忆化搜索)
来源:互联网 发布:淘宝优惠卷是真的假的 编辑:程序博客网 时间:2024/06/08 05:38
题目链接
题意:给定一张图,Matt要从M移动到T取偷东西,N,W,S,E表示这些位置有监控器,字母表示这些监控器的初始方向,并且每一秒顺时针旋转90度。现在Matt每移动一格需要花一秒,但是如果当前他所在的位置或者他要去的位置被监控器监视,那么如果他要移动,就必须躲在箱子里移动,时间需要花费3秒。或者也可以选择不移动,躲在箱子里1秒,问说Matt最少花费多少时间移动到T。
思路:借鉴的是小伙伴的想法,先预处理整张图,用二进制表示在一个周期(4S)内每个格子是否会被监控器监控到,之后状态要多开一维,表示4S一个周期,然后进行状态转移。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;const int MAXN = 505;const int INF = 0x3f3f3f3f;const int dx[] = {-1, 0, 1, 0};const int dy[] = {0, 1, 0, -1}; struct node{ node(int xx, int yy, int tt) { x = xx; y = yy; t = tt; } int x, y, t;};char map[MAXN][MAXN];int g[MAXN][MAXN], d[MAXN][MAXN][5];int n, sx, sy, ex, ey;int change(char c) { if (c == 'N') return 0; if (c == 'E') return 3; if (c == 'S') return 2; if (c == 'W') return 1; return -1;}int bfs(int x, int y, int t) { queue<node> q; node s(x, y, 0); q.push(s); memset(d, INF, sizeof(d)); d[s.x][s.y][s.t] = 0; int ans = INF; while (!q.empty()) { node u = q.front(); q.pop(); node v = u; if (v.x == ex && v.y == ey) ans = min(ans, d[v.x][v.y][v.t]); v.t = (v.t + 1) % 4; if (d[v.x][v.y][v.t] > d[u.x][u.y][u.t] + 1) { d[v.x][v.y][v.t] = d[u.x][u.y][u.t] + 1; q.push(v); } for (int i = 0; i < 4; i++) { node v = u; v.x = u.x + dx[i]; v.y = u.y + dy[i]; int step = 0; if (v.x < 0 || v.x >= n || v.y < 0 || v.y >= n || g[v.x][v.y] == -1) continue; if ((g[u.x][u.y] & (1<<u.t)) || (g[v.x][v.y] & (1<<u.t))) { v.t = (v.t + 3) % 4; step = 3; } else { v.t = (v.t + 1) % 4; step = 1; } if (d[v.x][v.y][v.t] > d[u.x][u.y][u.t] + step) { d[v.x][v.y][v.t] = d[u.x][u.y][u.t] + step; q.push(v); } } } return ans;}int main() { int cas, t = 1; scanf("%d", &cas); while (cas--) { scanf("%d", &n); memset(g, 0, sizeof(g)); memset(map, 0, sizeof(map)); for (int i = 0; i < n; i++) { scanf("%s", map[i]); for (int j = 0; j < n; j++) { if (map[i][j] == 'M') { sx = i; sy = j; } else if (map[i][j] == 'T') { ex = i; ey = j; } else if (map[i][j] == '#') g[i][j] = -1; else if (change(map[i][j]) != -1) { g[i][j] = 15; for (int k = 0; k < 4; k++) { int tx = i + dx[k]; int ty = j + dy[k]; if (tx < 0 || tx >= n || ty < 0 || ty >= n || map[tx][ty] == '#') continue; g[tx][ty] |= (1<<((change(map[i][j]) + k) % 4)); } } } } printf("Case #%d: ", t++); int ans = bfs(sx, sy, 0); if (ans >= INF) printf("-1\n"); else printf("%d\n", ans); } return 0;}
用记忆化搜索差点就超时了,所以用BFS+优先队列会更好,思想其实是差不多的。
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>using namespace std;const int N = 505;const int dx[] = {-1, 0, 1, 0, 0};const int dy[] = {0, -1, 0, 1, 0};int vis[N][N][5], b[N][N][5];char g[N][N];int n, sx, sy, ex, ey;struct node{ node(int xx, int yy, int dd) { x = xx; y = yy; d = dd; } int x, y, d; friend bool operator < (node a, node b) { return a.d > b.d; }};int bfs(int x,int y) { priority_queue <node> q ; node s(x, y, 0); q.push(s) ; memset(vis,0,sizeof(vis)) ; vis[x][y][0] = 1 ; while(!q.empty()) { node u = q.top() ; q.pop(); if(u.x == ex && u.y == ey) return u.d ; for(int i = 0 ;i < 5 ;i++) { int tx = u.x + dx[i] ; int ty = u.y + dy[i] ; if(tx < 0 || tx >= n || ty < 0 || ty >= n || g[tx][ty] == '#')continue ; node p = u; if(b[tx][ty][u.d%4] || b[u.x][u.y][u.d%4]) { if(tx == u.x && ty == u.y && !vis[tx][ty][(u.d+1)%4]) { p.d++ ; vis[tx][ty][p.d%4]=1 ; q.push(p) ; } else if(!vis[tx][ty][(u.d+3)%4]) { p.x=tx; p.y=ty ; p.d += 3 ; vis[tx][ty][p.d%4]=1 ; q.push(p) ; } } else if(!vis[tx][ty][(u.d+1)%4]) { p.x=tx; p.y=ty; p.d++ ; vis[tx][ty][p.d%4]=1 ; q.push(p) ; } } } return -1 ;}int main() { int cas, t = 1; scanf("%d", &cas); while (cas--) { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%s", g[i]); memset(b, 0, sizeof(b)); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { if (g[i][j] == 'M') { sx = i; sy = j; } else if (g[i][j] == 'T') { ex = i; ey = j; } else if (g[i][j] == 'N') { b[i][j][0] = b[i][j][1] = b[i][j][2] = b[i][j][3] = 1; if (i - 1 >= 0) b[i - 1][j][0] = 1; if (j + 1 < n) b[i][j + 1][1] = 1; if (i + 1 < n) b[i + 1][j][2] = 1; if (j - 1 >= 0) b[i][j - 1][3] = 1; } else if (g[i][j] == 'W') { b[i][j][0] = b[i][j][1] = b[i][j][2] = b[i][j][3] = 1; if (j - 1 >= 0) b[i][j - 1][0] = 1; if (i - 1 >= 0) b[i - 1][j][1] = 1; if (j + 1 < n) b[i][j + 1][2] = 1; if (i + 1 < n) b[i + 1][j][3] = 1; } else if (g[i][j] == 'S') { b[i][j][0] = b[i][j][1] = b[i][j][2] = b[i][j][3] = 1; if (i + 1 < n) b[i + 1][j][0] = 1; if (j - 1 >= 0) b[i][j - 1][1] = 1; if (i - 1 >= 0) b[i - 1][j][2] = 1; if (j + 1 < n) b[i][j + 1][3] = 1; } else if (g[i][j] == 'E') { b[i][j][0] = b[i][j][1] = b[i][j][2] = b[i][j][3] = 1; if (j + 1 < n) b[i][j + 1][0] = 1; if (i + 1 < n) b[i + 1][j][1] = 1; if (j - 1 >= 0) b[i][j - 1][2] = 1; if (i - 1 >= 0) b[i - 1][j][3] = 1; } } printf("Case #%d: %d\n", t++, bfs(sx, sy)); } return 0;}
1 0
- HDU5040- Instrusive(BFS+记忆化搜索)
- HDU5040 Instrusive,bfs+优先队列
- hdu5040 bfs
- HDU1428(BFS+DFS+记忆化搜索)
- FZU 2092 记忆化搜索 || BFS
- HDU 5012 Dice (bfs + 记忆化搜索)
- hdu 4230 bfs+记忆化搜索
- HDOJ-1428-BFS+记忆化搜索
- hdu5040 优先队列+bfs
- hdu5040 (2014北京网赛1009) Instrusive
- hdu 5040 Instrusive(BFS)
- hdu 5040 Instrusive (bfs)
- hdu 5040 Instrusive(BFS)
- hdu5040(bfs,优先队列)
- HDU 5040 Instrusive 搜索
- 【搜索】 HDOJ 5040 Instrusive
- hdu 1428 漫步校园 优先队列BFS +记忆化搜索
- ZOJ Walk Through the Forest (dijkstra + BFS || 记忆化搜索)
- Oralce新建数据库、新建远程登录用户全过程
- 0923
- MFC、WTL 、ATL、STL联系与区别
- Python __name__的问题
- python中thread的setDaemon、join的用法
- HDU5040- Instrusive(BFS+记忆化搜索)
- 鼠标点击地面人物自动走动(也包含按键wasd&space控制) .
- 小黑小波比.Ubuntu下安装Intellij IDEA和java的环境变量
- 修改itunesConnect Status (Developer Rejected 修改为Prepare for Submission)
- UVA - 10020 Minimal coverage(区间覆盖问题)
- Android运行时ART简要介绍
- 新建Oracle数据库的3种方法
- android launcher梳理
- JavaScript实现异步的4种方法