dfs+bfs(双剪枝)

You have a maze with obstacles and non-zero digits in it:

You can start from any square, walk in the maze, and finally stop at some square. Each step, you may only walk into one of the four neighbouring squares (up, down, left, right) and you cannot walk into obstacles or walk into a square more than once. When you finish, you can get a number by writing down the digits you encounter in the same order as you meet them. For example, you can get numbers 9784, 4832145 etc. The biggest number you can get is 791452384, shown in the picture above.

Your task is to find the biggest number you can get.

Input

There will be at most 25 test cases. Each test begins with two integers RR and CC (2R,C152≤R,C≤15, RC30R∗C≤30), the number of rows and columns of the maze. The next RR rows represent the maze. Each line contains exactly CC characters (without leading or trailing spaces), each of them will be either '#' or one of the nine non-zero digits. There will be at least one non-obstacle squares (i.e. squares with a non-zero digit in it) in the maze. The input is terminated by a test case with R=C=0R=C=0, you should not process it.

Output

For each test case, print the biggest number you can find, on a single line.

Samples

Input Copy
3 7
##9784#
##123##
##45###
0 0
Output
791452384



这个题的意思就是:给定一个n和m,在n×m的迷宫中,每个点为1-9或‘#‘,‘#’为障碍物不可经过,每个点仅可经过一次,将遇到的数字按遇到的顺序写下来,问这个数最大时为多少?
这个题如果只是普通的dfs一定会超时的,
这里必须要优化一下:

  剪枝一:经过每个点时,比较 能够到达的点+经过的点的个数 和当前最大值的长度maxlen,如果小于maxlen结束当前递归,这个判断是可以用BFS做的

  剪纸二:如果len==maxlen,则从前往后比较每一位的大小,如果有一位小于当前最大值,则结束当前的递归


#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn=30;
char a[maxn][maxn];
int vis[maxn][maxn];
int vis1[maxn][maxn];
string ans;
int n,m;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int maxlen=0;
int judge(int x,int y,int len,string s){//bfs剪枝判断
    memset(vis1,0,sizeof(vis1));
    queue<pair<int,int>> q;
    vis1[x][y]=1;
    q.push({x,y});
    len++;
    while(!q.empty()){
        auto p=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int xx=p.first+dx[i];
            int yy=p.second+dy[i];
            if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&a[xx][yy]!='#'&&!vis[xx][yy]&&!vis1[xx][yy]){
                vis1[xx][yy]=1;
                q.push({xx,yy});
                len++;
            }
        }
    }
    if(len==maxlen){
        for(int i=0;i<s.length();i++){
            if(s[i]<ans[i])
                    return 0;
            else{
                if(s[i]>ans[i])
                    return 1;
                else if(s[i]==ans[i]&&i==s.length()-1)return 1;
            }
        }
    }
    if(len>maxlen){
        return 1;
    }
    return 0;
}
void dfs(int x,int y,string p,int len){
    if(len>maxlen){
        ans=p;
        maxlen=len; 
    } 
    if(len==maxlen){
        for(int i=0;i<len;i++){
            if(p[i]<ans[i]){
                break;
            }
            else{
                if(p[i]>ans[i]){
                    ans=p;
                    break;
                }
            }
        }
    }
    for(int i=0;i<4;i++){
        int xx=x+dx[i];
        int yy=y+dy[i];
        if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&a[xx][yy]!='#'&&!vis[xx][yy]){
            if(judge(xx,yy,len,p)){//剪枝判断
                vis[xx][yy]=1;
                dfs(xx,yy,p+a[xx][yy],len+1);
                vis[xx][yy]=0;
            }
        }
    }
}
void inint(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            vis[i][j]=0;
        }
    }
}
int main(){
    while(scanf("%d%d",&n,&m)){
        if(n+m==0){
            break;
        }
        inint();
        maxlen=0;
        ans="";
        for(int i=1;i<=n;i++){
            scanf("%s",a[i]+1);
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(a[i][j]!='#'){
                    inint();
                    string z;
                    z+=a[i][j];
                    vis[i][j]=1;
                    dfs(i,j,z,1); 
                }    
            }
        }
        cout<<ans<<"\n";
    }
}

 

posted @ 2021-07-20 15:06  lipu123  阅读(96)  评论(0)    收藏  举报