【POJ】5335 - Walk Out 【BFS + 贪心】
2015-08-04 10:59
363 查看
题目
Walk OutTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3035 Accepted Submission(s): 620
Problem Description
In an n∗m maze,
the right-bottom corner is the exit (position (n,m) is
the exit). In every position of this maze, there is either a 0 or
a 1 written
on it.
An explorer gets lost in this grid. His position now is (1,1),
and he wants to go to the exit. Since to arrive at the exit is easy for him, he wants to do something more difficult. At first, he'll write down the number on position (1,1).
Every time, he could make a move to one adjacent position (two positions are adjacent if and only if they share an edge). While walking, he will write down the number on the position he's on to the end of his number. When finished, he will get a binary number.
Please determine the minimum value of this number in binary system.
Input
The first line of the input is a single integer T (T=10),
indicating the number of testcases.
For each testcase, the first line contains two integers n and m (1≤n,m≤1000).
The i-th
line of the next n lines
contains one 01 string of length m,
which represents i-th
row of the maze.
Output
For each testcase, print the answer in binary system. Please eliminate all the preceding 0 unless
the answer itself is 0 (in
this case, print 0 instead).
Sample Input
2 2 2 11 11 3 3 001 111 101
Sample Output
111 101
大意
给出一个由0和1组成的地图,求从左上角到右下角走过的路程中01的值组成的二进制所表示的值最小思路
找出使二进制长度最短的点, 从该点(可能有多个)开始以后每一步只可往右/下方向走,因为此时任何一个往左/上的操作都将是二进制长度增加,从而值增大算法过程:
第一步:
(1)当开头为0 时,需考虑前导0问题,bfs找出离左上角曼哈顿距离最远的点,则该点距右下角出口最近,所组成的二进制长度最短(点可能有多个,都加进求解队列a),此时有可能找到出口,则直接输出出口字符结束即可
(2)当开头为1时,直接把入口加入结果队列
第二步:
(1)对于当前求解队列a中的所有点(x, y) ,若存在0,则把0加入结果队列,并把此点可达点(x+1, y) 和(x, y+1)加入另一个求解队列b,若不存在0,则把所有队列中所有点的可达点(x+1, y)和(x, y+1)加入求解队列b,直到找到出口算法结束
(2)交换a,b队列,继续(1)
AC代码
#include <stdio.h> #include <string.h> char mp[1005][1005]; int T, n, m, ch, cnt, q[2][3000500], g = 0, c[2], mn; char re[2010], v[1005][1005]; void f(){ int mx = m + n + 1 - mn; //需要查找的位数 for (int i = 1; i <= mx; ++i){ char fg = 1; //当前求解队列a中是否存在0的标记 int tg = !g; //求解队列b的标记 c[tg] = -1; //求解队列b的长度 while (c[g] > 0){ int y = q[g][c[g]--]; int x = q[g][c[g]--]; if (x > n || y > m) continue; if (fg){ if (!v[x+1][y]){ q[tg][++c[tg]] = x+1; q[tg][++c[tg]] = y; v[x+1][y] = -1; //注意此处赋值-1是为了避免当求解队列a存在0时导致的可达点遗漏问题 } if (!v[x][y+1]){ q[tg][++c[tg]] = x; q[tg][++c[tg]] = y+1; v[x][y+1] = -1; } } if ('0' == mp[x][y]){ if (fg) c[tg] = -1; //第一次找到0,求解队列b清空 if (0 >= v[x+1][y]){ //未访问则加入 q[tg][++c[tg]] = x+1; q[tg][++c[tg]] = y; v[x+1][y] = 1; } if (0 >= v[x][y+1]){ q[tg][++c[tg]] = x; q[tg][++c[tg]] = y+1; v[x+1][y] = 1; } fg = 0; } } re[++cnt] = fg; g = !g; } } void bfs(){ memset(v, 0, sizeof(v)); cnt = -1; c[g] = -1; //当前广搜队列标志 int tg = !g; //最远点队列标志 q[g][++c[g]] = 1; //入口加入广搜队列 q[g][++c[g]] = 1; mn = 2; if ('0' == mp[1][1]){ //入口为0是bfs寻找最远点 int dir[][2] = {1, 0, -1, 0, 0, 1, 0, -1}; while (c[g] > 0){ int y = q[g][c[g]--]; int x = q[g][c[g]--]; if (x > 0 && y > 0 && x <= n && y <= m){ if (x == n && y == m){ re[++cnt] = mp[x][y] - '0'; return; } if (x + y > mn){ //找到更大值,更新最远点队列 mn = x + y; c[tg] = -1; q[tg][++c[tg]] = x; q[tg][++c[tg]] = y; }else if (x + y == mn){ //找到相同最大值,加入最远点队列 q[tg][++c[tg]] = x; q[tg][++c[tg]] = y; } for (int i = 0; i < 4; ++i){ //bfs if ('0' == mp[x + dir[i][0]][y + dir[i][1]] && !v[x + dir[i][0]][y + dir[i][1]]){ q[g][++c[g]] = x + dir[i][0]; q[g][++c[g]] = y + dir[i][1]; v[x + dir[i][0]][y + dir[i][1]] = 1; } } } } g = !g; //把最远点队列变成求解队列a交给f()使用 } f(); } int main() { scanf("%d", &T); char s[3010]; while (T--){ scanf("%d%d", &n, &m); gets(mp[0]); for (int i = 1; i <= n; ++i){ gets(mp[i] + 1); } bfs(); int i = 0; while (i < m + n && !re[i]) ++i; //除去前导0 if (i > cnt) printf("0"); while (i <= cnt) printf("%d", re[i++]); printf("\n"); } return 0; }
相关文章推荐
- LeetCode:Palindrome Linked List
- 国内从事GIS行业的公司及其网址
- 开源资源下载网站
- POJ 2709 混合颜料 acm 贪心
- HDU 2159 FATE(二维费用背包)
- 从零开始学Python
- 面试题40_数组中只出现一次的数字
- 套接字联网API之二 select作用和案例
- 一种打印螺旋式矩阵的方法
- 欢迎使用CSDN-markdown编辑器
- hadoop2.6伪分布+pig0.15+zookeeper3.4.6安装
- Android仿qq聊天记录长按删除功能效果
- subversion SVN
- [hdu1028]整数拆分,生成函数
- HTML5 FormData 用jquery 异步上传报错
- Android仿qq聊天记录长按删除功能效果
- php面向对象(OOP)编程完整教程
- iOS-UIkit复习和代理的使用实现文本框限制输入字数控制
- Eclipse全屏调试时,如何屏蔽控制台console弹出骚扰!!!
- oracle case where 复杂sql语句