题目字面意思是让?变成 . 或#,使得 . 可以连成一片,唯一就把图输出,不唯一就输出Ambiguous,否则Impossible.
先将所有的 . dfs遍历一遍,记录有几块相连的陆地数k,并记录扫过的格子数cnt_s,途中遇到的?就把它当成 . ,如果有没遇到的?说明被#包围,则这个?一定为#。遍历完后,如果k>1,那么肯定是Imossible,如果k为1,再把dfs过程中遇到的每一个?当成#,分别在dfs,计算相连的陆地数cnt,如果有cnt==cnt_s-1,那么有多解,否则解唯一。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define MAX_N 55
using namespace std;
char map[MAX_N][MAX_N];
int n,m;
int cnt_s;
int cnt_p;
int cnt;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
bool vis[MAX_N][MAX_N];
void dfs(int sx,int sy)
{
vis[sx][sy]=true;
for(int i=0;i<4;i++)
{
int tx=sx+dx[i];
int ty=sy+dy[i];
if(tx>=0&&tx<n&&ty>=0&&ty<m&&map[tx][ty]!='#'&&!vis[tx][ty])
{
cnt++;
if(map[tx][ty]=='?')
map[tx][ty]='*';//标记走过的?
vis[tx][ty]=true;
dfs(tx,ty);
}
}
return ;
}
int main(void)
{
while(scanf("%d%d",&n,&m)==2)
{
cnt_p=0;
int sx,sy;
for(int i=0;i<n;i++)
scanf("%s",map[i]);
memset(vis,false,sizeof(vis));
int k=0;//k块陆地
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(map[i][j]=='.'&&!vis[i][j])
{
k++;
cnt=1;
dfs(i,j);
sx=i;
sy=j;
}
}
}
if(k>1)
{
printf("Impossible\n");
continue;
}
cnt_s=cnt;
bool ok=false;
for(int i=0;i<n&&!ok;i++)
{
for(int j=0;j<m&&!ok;j++)
{
cnt=1;
if(map[i][j]=='*')
{
memset(vis,false,sizeof(vis));
map[i][j]='#';
dfs(sx,sy);
if(cnt==cnt_s-1)
ok=true;
map[i][j]='.';
}
}
}
if(ok)
printf("Ambiguous\n");
else
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(map[i][j]=='.')
printf("."`
;
else
printf("#");
}
printf("\n");
}
}
}
return 0;
}