Biggest Number
题意
Biggest Number - UVA 11882 - Virtual Judge (vjudge.net)
寻找最大的数。
思路
dfs(回溯)+剪枝(bfs).由于string的大小比较和本题数字的大小比较类似,所以用string更方便。每一次dfs时要考虑当前节点之后所能串起来的数的个数
,分为三种情况:1,数的个数
太少,显然不满足,跳过当前的节点的dfs(剪枝);2,数的个数
+当前的长度now能跟之前一样长,那就比较ans的子字符串跟当前的now字符串谁大,如果ans大那就没必要继续(剪枝);3,数的个数
+当前now的长度比ans的长度更长,那就显然拼接后的更大,要及时更新。
int r,c;
int vis[maxn][maxn],visb[maxn][maxn];
string a[maxn],ans;
int v[][2]={{-1,0},{1,0},{0,-1},{0,1}};
struct node{
int x,y;
};
void update(string now) {
if(ans.size()<now.size() || (ans.size()==now.size() && ans<now)) ans=now;
}
bool in_area(int x,int y) {
return x>=0 && x<r && y>=0 && y<c;
}
int bfs(int x,int y) {
int relax=0;
queue<node> q;
q.push({x,y});
memcpy(visb,vis,sizeof vis);
visb[x][y]=1;
while (!q.empty()) {
x=q.front().x,y=q.front().y;
q.pop();
for(int i=0;i<4;i++) {
int xi=x+v[i][0],yi=y+v[i][1];
if(!in_area(xi,yi)) continue;
if(!visb[xi][yi]) {
visb[xi][yi]=1;
if(a[xi][yi]=='#') continue;
q.push({xi,yi});
relax++;
}
}
}
return relax;
}
void dfs(int x,int y,string now) {
int relax=bfs(x,y),sz=(int)now.size(),asz=(int)ans.size();
if(sz+relax<asz) return ;
if(ans.substr(0,sz)>now && sz+relax==asz) return ;
update(now);
for(int i=0;i<4;i++) {
int xi=x+v[i][0],yi=y+v[i][1];
if(!in_area(xi,yi)) continue;
if(!vis[xi][yi] && a[xi][yi]!='#') {
vis[xi][yi]=1;
if(a[xi][yi]=='#') continue;
dfs(xi,yi,now+a[xi][yi]);
vis[xi][yi]=0;
}
}
}
int main(int argc, char const *argv[]) {
while (~scanf("%d%d",&r,&c)&&r) {
ans="";
qwe(i,0,r-1) cin>>a[i];
qwe(i,0,r-1) {
qwe(j,0,c-1) {
if(a[i][j]=='#') continue;
mem(vis,0);
vis[i][j]=1;
string now;
now=a[i][j];
dfs(i,j,now); // 初始值不要忘
}
}
std::cout << ans << '\n';
}
return 0;
}