hdoj 5335 bfs
来源:互联网 发布:2017最新网络综艺节目 编辑:程序博客网 时间:2024/05/17 08:35
hdoj 5335
题意:给一个n*m的矩阵,矩阵中每小块上有个数字1或0, 一个人从(1,1)点走到(n,m)点,记录沿途的数字,问这个数字最小是多少。
思路:先找出发点,如果(1,1)是1,那就从(1,1)开始往右和往下搜,这样可以保证曼哈顿距离递减,数字长度为n+m是最短的;如果(1,1)不是1,那就从(1,1)开始搜起点,这个起点必须是从(1,1)能到达的最远的数字为1的块,这样距离终点也是最近的。对于所有这样的块,开始往右往下搜,使曼哈顿距离递减,搜到的点如果有0,答案中就记0,并且继续只从0点搜;如果没有0,答案中就记1,并从1点搜。
其实思路一直都很清晰,但是一直各种错。。还是我弱啊
#include <cstdio>#include <cstring>#include <queue>using namespace std;int n, m;struct Node{ int x, y;};int ans[2048];bool vis[1005][1005];queue<Node>q;const int M = 1005;char str[M][M];int d[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};int bfs() { memset(vis, 0, sizeof vis); while(!q.empty()) q.pop(); Node node; node.x = 1, node.y = 1; q.push(node); vis[node.x][node.y] = true; if(str[1][1] == '1') return 2; int maxn = 0; while(!q.empty()) { node = q.front(); q.pop(); if(node.x == n && node.y == m) return m + n; for(int i = 0; i < 4; i++) { Node t = node; t.x = node.x + d[i][0], t.y = node.y + d[i][1]; if(t.x < 1 || t.x > n || t.y < 1 || t.y > m || vis[t.x][t.y]) continue; vis[t.x][t.y] = true; if(t.x + t.y > maxn) maxn = t.x + t.y; if(str[t.x][t.y] == '0') q.push(t); } } return maxn;}int cnt;queue<Node> q0[2], q1[2];void solve(int a) { for(int i = 0; i < 2; i++) { while(!q0[i].empty()) q0[i].pop(); while(!q1[i].empty()) q1[i].pop(); } cnt = 0; int now, id = 0; now = a; for(int i = 1; i <= n; i++){ int j = a - i; if(j >= 1 && j <= m && str[i][j] == '1' && vis[i][j]){ Node node; node.x = i, node.y = j; q1[0].push(node); } } while(now <= m + n){ memset(vis, 0, sizeof vis); while(!q0[id ^ 1].empty()) q0[id ^ 1].pop(); while(!q1[id ^ 1].empty()) q1[id ^ 1].pop(); if(q0[id].size() > 0){ ans[cnt++] = 0; if(now == m + n) break; while(!q0[id].empty()){ Node node = q0[id].front(); q0[id].pop(); for(int i = 0; i < 2; i++){ Node t = node; t.x += d[i][0], t.y += d[i][1]; if(t.x < 1 || t.x > n || t.y < 1 || t.y > m || vis[t.x][t.y]) continue; vis[t.x][t.y] = true; if(str[t.x][t.y] == '0') q0[id ^ 1].push(t); else q1[id ^ 1].push(t); } } } else if(q1[id].size() > 0){ ans[cnt++] = 1; if(now == m + n) break; while(!q1[id].empty()) { Node node = q1[id].front(); q1[id].pop(); for(int i = 0; i < 2; i++){ Node t = node; t.x += d[i][0], t.y += d[i][1]; if(t.x < 1 || t.x > n || t.y < 1 || t.y > m || vis[t.x][t.y]) continue; vis[t.x][t.y] = true; if(str[t.x][t.y] == '0') q0[id ^ 1].push(t); else q1[id ^ 1].push(t); } } } id ^= 1; now++; }}main() { // freopen("in.txt", "r", stdin); int t; scanf("%d", &t); while(t--){ scanf("%d %d", &n, &m); for(int i = 1; i <= n; i++) scanf("%s", &str[i][1]); int a = bfs(); if(a == n + m && str[n][m] == '0') { puts("0"); continue; } else { solve(a); for(int i = 0; i < cnt; i++) printf("%d", ans[i]); putchar('\n'); } }}
0 0
- hdoj 5335 bfs
- HDOJ 5335 Walk Out 贪心+BFS
- hdoj 1242 Rescue(bfs)
- HDOJ 1072 Nightmare (bfs)
- HDOJ 2364 Escape (bfs)
- hdoj 2364 Escape(BFS)
- HDOJ 1072 Nightmare bfs
- Hdoj 1424 Rescue 【BFS】
- hdoj 1242 Rescue (BFS)
- hdoj Asteroids! (BFS)
- hdoj 1242 Rescue [BFS]
- hdoj 5040 bfs
- hdoj 1072 Nightmare 【bfs】
- HDOJ 1242 Rescue【BFS】
- hdoj 1242 Rescue 【bfs】
- hdoj 5637 Transform 【BFS】
- HDOJ 2612 bfs
- HDOJ-----1242BFS
- Activity中获取view的高度和宽度方法
- TinkPHP 3.2.3版本 新手该注意的地方
- python 接收邮件
- UIday0702:用 UIScrollView 和 UIPageControl 实现引导图
- Centos NAT网络配置
- hdoj 5335 bfs
- CentOS下安装配置LAMP(Linux+Apache+MySQL+PHP)
- UI多线程编程小练习--卖票系统
- 欢迎使用CSDN-markdown编辑器
- 创建String类型的数组,动态初始化数组
- opencv学习笔记(二)—显示图像
- A. Bear and Poker
- 文章标题
- Tsung简易教程-CentOS版