GYM Samara16 A Treasure Island 暴力

来源:互联网 发布:淘宝企业店铺 企业资质 编辑:程序博客网 时间:2024/09/21 06:18
题意:n*m的地图,'#'表示障碍, '.'表示land, '?'表示待定. 可以上下左右移动.
问是否能将地图上所有的'?'变为'.'或者'#' 使得地图上只有一个联通分量.
n,m<=50. 无解输出impossible ,若有多解 则输出ambiguous. 只有一解输出变化后的地图.


先把所有的'?'都变为'.' 还是有多少个联通分量时
如果有某个个联通分量全部都为'?则把该摧毁该连通分量,直到联通分量个数为1为止.
若此时联通分量个数还是>1则无解.


现在只有一个联通分量 
若把'?'的某个集合{p1,p2,..pk] 由'.'变为'#'时联通分量个数还是1.那么单独把某个pi变为'#',此时联通分量个数还是1.

枚举把某个'?'由'.'变为'#' 若此时联通分量个数还是1,则有多解 O(n^2 m^2).

#include <bits/stdc++.h>using namespace std;typedef pair<int,int> ii;const int N=55;char s[N][N];int n,m,vis[N][N],mp[N*N],num=0,tot=0;int dx[]={-1,1,0,0};int dy[]={0,0,-1,1};vector<ii> a;void dfs(int x,int y){vis[x][y]=1;tot++;if(s[x][y]=='?')num++;for(int i=0;i<4;i++){int a=x+dx[i],b=y+dy[i];if(a>=1&&a<=n&&b>=1&&b<=m&&(!vis[a][b])&&s[a][b]!='#')dfs(a,b);}}void fun(int x,int y){vis[x][y]=1;s[x][y]='#';//cout<<x<<' '<<y<<endl;for(int i=0;i<4;i++){int a=x+dx[i],b=y+dy[i];if(a>=1&&a<=n&&b>=1&&b<=m&&(!vis[a][b])&&s[a][b]=='?')fun(a,b);}}int check(){int cnt=0;memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(s[i][j]!='#'&&!vis[i][j])dfs(i,j),cnt++;return cnt;}int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%s",s[i]+1);for(int j=1;j<=m;j++)if(s[i][j]=='?')a.push_back(ii(i,j));}int p=0;if(check()>1){for(int i=0;i<a.size();i++){if(s[a[i].first][a[i].second]=='#')continue; num=tot=0;memset(vis,0,sizeof(vis));dfs(a[i].first,a[i].second);//cout<<i<<' '<<num<<' '<<tot<<endl;if(num==tot){memset(vis,0,sizeof(vis));fun(a[i].first,a[i].second);}}if(check()>1){puts("Impossible");return 0;}}bool flag=true;for(int i=p;i<a.size();i++){int x=a[i].first,y=a[i].second;if(s[x][y]=='#')continue;s[x][y]='#';if(check()==1)flag=false;s[x][y]='.';}if(!flag)puts("Ambiguous");elsefor(int i=1;i<=n;i++)printf("%s\n",s[i]+1);return 0;}


原创粉丝点击