【题意】:
链接:gym100971—A Treasure Island
给你n,m。然后给你一张n*m的地图,'#' 表示水,'.' 表示陆地,‘?' 表示不确定,可能是水可能是陆地。已知,这张地图上只有一片连续的陆地,问你是否能还原这张地图,如果不可能输出Impossible,答案不唯一输出Ambiguous,答案唯一的话,将‘ ?’还原成‘ # ’或者‘ . ’。
【题解】:
教训:能暴力点就暴力点,让脑子轻松点。
首先把‘ ?’当作‘ . ',从一个陆地点开始搜索,求一下所有陆地点是否是一个联通块,如果不连通,那么必然是Impossible,同时标记搜到的每一个’ ? '和' . '为来过。
然后暴力for图中的每一个被标记为来过的‘ ?’,把这个 点暂时改成‘ # ’,然后重复刚才的搜索,判断所有陆地点是否是一个联通块,搜索完毕后改回‘ ?’,如果存在一个‘ ?’,哪怕被改成‘ # ‘,所有陆地点还是属于一个联通块,那么答案必定是Ambiguous.
不然答案唯一,将第一次搜索标记为来过的’ ? ' 改成 ‘ . ',没被标记的‘ ?‘改成 ’ # ‘。输出答案即可。
#include<bits/stdc++.h>
using namespace std;
int n,m,vis[55][55],vis2[55][55];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
char ch[55][55];
void dfs(int i,int j)
{
vis[i][j]=1;
for(int g=0;g<4;g++){
int x=i+dir[g][0];
int y=j+dir[g][1];
if(x>0&&x<=n&&y>0&&y<=m&&vis[x][y]==0&&ch[x][y]!='#'){
dfs(x,y);
}
}
}
int solv()
{
int cnt=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(vis[i][j]==0&&ch[i][j]=='.'){
cnt++;
dfs(i,j);
}
}
}
return cnt;
}
int main(void)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",ch[i]+1);
}
int num=solv();
if(num>1) return 0*printf("Impossible\n");
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
vis2[i][j]=vis[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(ch[i][j]=='?'&&vis2[i][j]==1){
ch[i][j]='#';
memset(vis,0,sizeof(vis));
num=solv();
if(num==1) return 0*printf("Ambiguous\n");
ch[i][j]='?';
}
}
}
memset(vis,0,sizeof(vis));
solv();
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(ch[i][j]=='?'){
if(vis[i][j]==0){
ch[i][j]='#';
}
else{
ch[i][j]='.';
}
}
}
printf("%s\n",ch[i]+1);
}
return 0;
}