F - Biggest Number
F - Biggest Number
题意:给定一个n和m,在n×m的迷宫中,每个点为1-9或'#',‘#’为障碍物不可经过,每个点仅可经过一次,将遇到的数字按遇到的顺序写下来,问这个数最大时为多少?
解法:bfs搜索,加双剪纸。
剪枝一:经过每个点时,比较 能够到达的点+经过的点的个数 和当前最大值的长度maxlen,如果小于maxlen结束当前递归
剪纸二:如果len==maxlen,则从前往后比较每一位的大小,如果有一位小于当前最大值,则结束当前的递归
#include<bits/stdc++.h> using namespace std; int n,m; string s[33]; bool vis[33][33],vis2[33][33]; int dir[4][2]={0,1,0,-1,1,0,-1,0}; int maxlen=0; string maxs; bool check(int x,int y,int len,string ss){ memset(vis2,0,sizeof(vis2)); queue<pair<int,int>> q; vis2[x][y]=1; q.push({x,y}); len++; while(!q.empty()){ for(int i=0;i<4;i++){ int xx=q.front().first+dir[i][0],yy=q.front().second+dir[i][1]; if(xx>=0&&yy>=0&&xx<n&&yy<m&&s[xx][yy]!='#'&&!vis[xx][yy]&&!vis2[xx][yy]){ vis2[xx][yy]=1; q.push({xx,yy}); len++; } } q.pop(); } if(len==maxlen){ for(int i=0;i<ss.length();i++){ if(ss[i]<maxs[i]) return 0; else{ if(ss[i]>maxs[i]) return 1; else if(ss[i]==maxs[i]&&i==ss.length()-1)return 1; } } } if(len>maxlen){ return 1; } return 0; } void dfs(int x,int y,int len,string ss){ //cout<<ss<<endl; //cout<<"maxlen: "<<maxlen<<endl; if(len>maxlen){ maxlen=len; maxs=ss; } if(len==maxlen){ for(int i=0;i<ss.length();i++){ if(ss[i]<maxs[i]){ break; }else{ if(ss[i]>maxs[i]){ maxs=ss; break; } } } } for(int i=0;i<4;i++){ int xx=x+dir[i][0],yy=y+dir[i][1]; if(xx>=0&&yy>=0&&xx<n&&yy<m&&s[xx][yy]!='#'&&!vis[xx][yy]){ if(check(xx,yy,len,ss)){ vis[xx][yy]=1; dfs(xx,yy,len+1,ss+s[xx][yy]); vis[xx][yy]=0; } } } return; } void init(){ memset(vis,0,sizeof(vis)); maxlen=0; maxs=""; return; } int main(){ while(cin>>n>>m){ if(!n&&!m) break; init(); for(int i=0;i<n;i++){ cin>>s[i]; } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(s[i][j]!='#'){ memset(vis,0,sizeof(vis)); vis[i][j]=1; string cnt;cnt+=s[i][j]; dfs(i,j,1,cnt); } } } cout<<maxs<<endl; } }