HDU 5335 Walk Out(BFS+BFS) 经典 2015 Multi-University Training Contest 4
2015-07-30 21:27
609 查看
Walk Out
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 506 Accepted Submission(s): 84
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
Author
XJZX
Source
2015 Multi-University Training Contest 4
题意:要求从(0,0)走到(n-1 , m-1)经过的位置里的值组合成二进制数值最小。
解题:先用BFS从(0,0)出发,去掉前导0,找出离(n-1 , m-1 )最近的一些位置为1,然后再从找出的这些位置开始出发(每个位置只走一次),用两个数组模似两个队列,交换使用,每次队列里面的位置值要么全为0,要么全为1,这样即保证了最短长度,而且也保证了字典序最小。
5
15 15
101010111011010
110011011000111
100011110100100
101101100110011
100011000110011
100111111111001
101001101001100
100101001100110
100111111000010
101001001000110
101100100110100
100100110010010
110100100100110
100010010010001
111111111001001
10100000000000000100100001001
#include<stdio.h> #include<queue> #include<iostream> #include<string.h> #include<string> using namespace std; const int N = 1015; char mapt[N*N]; int fath[N*N],vist[N*N],dir[4][2]={1,0,0,1,0,-1,-1,0}; int n,m; int inq[2],q[2][N*N] , tq[N*N] , minlen; int ABS(int aa){return aa>0?aa:-aa;} void bfs1(int st) { int x,y,kk=0; memset(vist,0,sizeof(vist)); inq[0]=inq[1]=0; minlen=ABS(n-1-st/m)+ABS(m-1-st%m);//找一个位置为1的离(n-1,m-1)位置最近的一些点 if(mapt[st]=='0') tq[kk++]=st; vist[st]=1; while(kk) { st=tq[--kk]; x=st/m; y=st%m; for(int e=0; e<4; e++) { int tx=x+dir[e][0] , ty=y+dir[e][1]; if(tx>=0&&tx<n&&ty>=0&&ty<m&&vist[tx*m+ty]==0) { if(mapt[tx*m+ty]=='0') tq[kk++]=tx*m+ty; else { int tlen=ABS(n-1-tx)+ABS(m-1-ty); if(minlen>tlen)minlen=tlen; } vist[tx*m+ty]=1; } } } for(int i=0; i<n; i++) for(int j=0; j<m; j++) if(vist[i*m+j]==1&&mapt[i*m+j]=='1'&&ABS(n-1-i)+ABS(m-1-j)==minlen) { q[0][inq[0]++]=i*m+j; } } void bfs2(int endd) { int x,y,st,flag=0; memset(fath,-1,sizeof(fath)); //两个队列交换使用保证序列的长度一样 while(inq[flag]) { bool bb=0; //队列里的位置所在的格子值要么全是0,要么全1,这要才能保证字典序最小 for(int i=0; i<inq[flag]; i++) { st=q[flag][i]; x=st/m; y=st%m; for(int e=0; e<2; e++)//走两个方向:向右向下 { int tx=x+dir[e][0] , ty=y+dir[e][1] ; int tst=tx*m+ty; if(tx>=0&&tx<n&&ty>=0&&ty<m) if(mapt[tst]=='0'&&vist[tst]==0)//先找0 { fath[tst]=st; vist[tst]=1+vist[st]; if(tst==endd) { return ; } q[!flag][inq[!flag]++]=tst; bb=1; } } } if(bb==0) for(int i=0; i<inq[flag]; i++) { st=q[flag][i]; x=st/m; y=st%m; for(int e=0; e<2; e++) { int tx=x+dir[e][0] , ty=y+dir[e][1] ; int tst=tx*m+ty; if(tx>=0&&tx<n&&ty>=0&&ty<m) if(mapt[tst]=='1'&&vist[tst]==0) { fath[tst]=st; vist[tst]=1+vist[st]; if(tst==endd) { return ; } q[!flag][inq[!flag]++]=tst; } } } inq[flag]=0; flag=!flag; } } char str[N*N]; void prin(int endd) { int k=0; while(endd!=-1) { //printf("<-(%d,%d)%c ",endd/m,endd%m,mapt[endd]); str[k++]=mapt[endd]; endd=fath[endd]; } while(k--) { printf("%c",str[k]); } printf("\n"); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0; i<n; i++) { scanf("%s",str); for(int j=0; j<m; j++) mapt[i*m+j]=str[j]; } int endd=n*m-1; bfs1(0); if(vist[endd]!=0) { printf("%c\n",mapt[endd]); } else { bfs2(endd); prin(endd); } } }
相关文章推荐
- 2015 Multi-University Training Contest 4 hdu 5335 Walk Out
- 2015 Multi-University Training Contest 4
- 2015 Multi-University Training Contest 4 -- Walk Out
- hdu 5325 Crazy Bobo 附上证明 Multi-University Training Contest 3
- sockaddr和sockaddr_in的区别 http://blog.csdn.net/joeblackzqq/article/details/8258693
- hdu 5319 Painter(模拟题)
- "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突问题
- STM32F4XX devices vector table for EWARM toolchain.
- 邮件服务器之Webmail
- SVN Cleanup failed to process the following paths
- HDOJ 1022 Train Problem I(栈)
- Aircrack-ng支持网卡列表(上)
- 出现 duplicate symbols for architecture arm**,linker command failed with exit code 1错误解决办法
- hdu 5335 Walk Out (2015 Multi-University Training Contest 4)
- 一个类的字段存取器,分别在什么场合需要用 assign、copy、retain呢?
- STM32F1XX devices vector table for EWARM toolchain.
- apt-get update时卡在 waiting for headers
- HDU 5336 XYZ and Drops 2015 Multi-University Training Contest 4 1010
- 解决Failed to connect session for conifg 故障
- 2015 Multi-University Training Contest 4 (hdu 5335、5336)模拟