BJFU 1406

Walk Out

時間限制(C/C++):5000MS/10000MS          運行內存限制:81920KByte

描述

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.

輸入

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.

輸出

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).


這題是一道bfs搜索題,但如果只用一次bfs會超時,所以需要用兩次bfs

第一次bfs搜索起點位置(也就是從起點開始搜索爲0的路徑),選出裏重點最近的起點。可以通過比較x+y的大小得出。

第二次bfs從第一次bfs得出的起點開始搜索路徑,搜索中,如果存在爲0的路徑則棄掉所有爲1 的路徑,否則值爲1的路徑全部存入。

有一點需要注意的是,長寬均爲1 的時候需要特判,否則會出現死循環的錯誤。

這種算法有一個問題就是如果起點(0,0)爲1的話第一次bfs就會無效,接下來就相當於還是隻用一次bfs求路徑,所以可能會超時,這個算法有待改進。

#include<iostream>      
#include<stdio.h>    
#include<math.h>    
#include<string>        
#include<vector>    
#include<queue>    
#include<algorithm>        
using namespace std;   
char a[1005][1005]; 
int vis[1005][1005]; 
int fang[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; 
int n,m,flag; 
int shu[3000]; 
struct point 
{ 
    int x; 
    int y; 
    int step; 
}; 
bool judge(int x,int y) //判斷是否越界
{ 
    if(x<0||x>=n||y<0||y>=m||vis[x][y]) 
        return false; 
    else return true; 
} 
int step; 
queue<point>q; 
void bfs(int x,int y) //搜索起點
{ 
    if(x==n-1&&y==m-1) //<span style="color:#ff0000;font-weight: bold;">特判是否長寬爲1且(0,0)點爲0</span>
    { 
        flag=1; 
        return ; 
    } 
    point max; 
    max.x=x; 
    max.y=y; 
    max.step=0; 
    int maxx=x+y; 
    queue<point>qq,qqq; 
    if(judge(x,y)&&a[x][y]=='0') 
    qq.push(max); 
    vis[x][y]=1; 
    while(!qq.empty()) 
    { 
        point t; 
        t=qq.front(); 
        qq.pop(); 
        for(int i=0;i<4;i++) 
        if(judge(t.x+fang[i][0],t.y+fang[i][1])) 
        { 
            vis[t.x+fang[i][0]][t.y+fang[i][1]]=1; 
            if(a[t.x+fang[i][0]][t.y+fang[i][1]]=='1') //如果爲1存入
            { 
            point tt; 
            tt.x=t.x+fang[i][0]; 
            tt.y=t.y+fang[i][1]; 
            tt.step=0; 
            qqq.push(tt); 
            if(t.x+fang[i][0]+t.y+fang[i][1]>maxx) 
            { 
                maxx=t.x+fang[i][0]+t.y+fang[i][1]; 
            } 
            } 
            if(a[t.x+fang[i][0]][t.y+fang[i][1]]=='0') //如果爲0繼續判斷
            { 
                if(t.x+fang[i][0]==n-1&&t.y+fang[i][1]==m-1) //已經搜索到終點(數組全爲0)
                { 
                    flag=1; 
                    return ; 
                } 
                point tt; 
                tt.x=t.x+fang[i][0]; 
                tt.y=t.y+fang[i][1]; 
                tt.step=0; 
                qq.push(tt); 
            } 
        } 
    } 
    while(!qqq.empty()) //找出最遠的起點
    { 
        point tp=qqq.front(); 
        qqq.pop(); 
        if(tp.x+tp.y==maxx)q.push(tp); 
    } 
} 
vector<point>zero; 
vector<point>one; 
int len; 
void bfs2() //搜索路徑
{ 
    while(1) 
    { 
        zero.clear(); 
        one.clear(); 
    while(!q.empty()) //這裏引入兩個vector數組分別用來儲存值爲0和1的路徑
    { 
        point t=q.front(); 
        q.pop(); 
        shu[t.step]=a[t.x][t.y]-'0'; 
        len=t.step; 
        if(t.x==n-1&&t.y==m-1)return ; //到達終點
        if(judge(t.x+1,t.y)&&a[t.x+1][t.y]=='1') 
        { 
            point tt; 
            tt.x=t.x+1; 
            tt.y=t.y; 
            tt.step=t.step+1; 
            vis[tt.x][tt.y]=1; 
            one.push_back(tt); 
        } 
        if(judge(t.x+1,t.y)&&a[t.x+1][t.y]=='0') 
        { 
            point tt; 
            tt.x=t.x+1; 
            tt.y=t.y; 
            tt.step=t.step+1; 
            vis[tt.x][tt.y]=1; 
            zero.push_back(tt); 
        } 
        if(judge(t.x,t.y+1)&&a[t.x][t.y+1]=='1') 
        { 
            point tt; 
            tt.x=t.x; 
            tt.y=t.y+1; 
            tt.step=t.step+1; 
            vis[tt.x][tt.y]=1; 
            one.push_back(tt); 
        } 
        if(judge(t.x,t.y+1)&&a[t.x][t.y+1]=='0') 
        { 
            point tt; 
            tt.x=t.x; 
            tt.y=t.y+1; 
            tt.step=t.step+1; 
            vis[tt.x][tt.y]=1; 
            zero.push_back(tt); 
        } 
    } 
        if(!zero.empty()) //如果存在值爲0的路徑存入隊列,值爲1的路徑刪除
        { 
            for(int i=0;i<zero.size();i++) 
                q.push(zero[i]); 
        } 
        else 
        { 
            for(int i=0;i<one.size();i++) 
                q.push(one[i]); 
        } 
    } 
} 
int main() 
{ 
    int T; 
    scanf("%d",&T); 
    while(T--) 
    { 
        memset(a,0,sizeof(a)); 
        memset(vis,0,sizeof(vis)); 
        memset(shu,0,sizeof(shu)); 
        len=0,flag=0; 
        while(!q.empty())q.pop(); 
        zero.clear(); 
        one.clear(); 
        scanf("%d%d",&n,&m); 
        for(int i=0;i<n;i++) 
                scanf("%s",a[i]); 
        if(a[0][0]=='1') 
        { 
            point aaa; 
            aaa.x=0; 
            aaa.y=0; 
            aaa.step=0; 
            q.push(aaa); 
        } 
        else bfs(0,0); 
        if(flag) 
        { 
            printf("0\n"); 
            continue; 
        } 
        bfs2(); 
        for(int i=0;i<=len;i++) 
            printf("%d",shu[i]); 
        printf("\n"); 
    } 
    return 0; 
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章