您的位置:首页 > 大数据 > 人工智能

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);
        }
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: