GYM 100971 A.Treasure Island(dfs+并查集)
来源:互联网 发布:品茗网络计划2014破解 编辑:程序博客网 时间:2024/05/18 01:09
Description
给出一张n*m的地图,点表示空地,井号表示墙,问号不确定,问是否可以把问号变成点或井号使得整张图只有一个连通块
Input
第一行两个整数n和m表示地图规模,之后一个n*m矩形表示该地图(1<=n,m<=50)
Output
如果存在唯一解则输出该唯一解,如果多解输出Ambiguous,如果无解输出Impossible
Sample Input
Sample Output
Solution
1.首先处理一些必须是#的?,即从每个点开始扫连通块,遇到问号就把问号变成点并标记,最后没有标记的问号就是一定变成#的;
2.然后判无解,即把没有处理的问号全部变成点再扫一遍连通块,用并查集维护下连通性,如果最后超过一个连通块说明无解;
3.然后判多解,即判是否存在一个问号使得将其变成#也能使得只有一个连通块,判的方法很简单,之前只有一个连通块时可以知道处于这个连通块中的点数cnt,现在开始枚举每个问号,把这个问号变成#然后开始扫连通块,如果连通块点数为cnt-1说明这个问号变成#也行,那么就多解了,否则把这个问号变成点接着去找下一个问号;
4.始终不出现多解的情况说明有唯一解
Code
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define maxn 2555char s[55][55],ss[55][55];int n,m,fa[maxn],num[maxn];void init(){ for(int i=1;i<=n*m;i++)fa[i]=i,num[i]=1;}int find(int x){ if(fa[x]==x)return x; return fa[x]=find(fa[x]);}void unite(int x,int y){ x=find(x),y=find(y); if(x==y)return ; fa[y]=x; num[x]+=num[y]; }int dx[]={-1,0,1,0};int dy[]={0,-1,0,1};int P(int x,int y){ return (x-1)*m+y;} int deal(){ init(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(ss[i][j]=='.') for(int k=0;k<4;k++) { int ii=i+dx[k],jj=j+dy[k]; if(ii<1||ii>n||jj<1||jj>m||ss[ii][jj]!='.')continue; unite(P(i,j),P(ii,jj)); } int cnt=0,ans; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(ss[i][j]=='.'&&fa[P(i,j)]==P(i,j)) cnt++,ans=num[P(i,j)]; if(cnt>1)return -1; return ans;}int vis[55][55];void dfs(int x,int y){ vis[x][y]=1; for(int k=0;k<4;k++) { int ii=x+dx[k],jj=y+dy[k]; if(ii<1||ii>n||jj<1||jj>m||vis[ii][jj]||ss[ii][jj]=='#')continue; dfs(ii,jj); }}int main(){ while(~scanf("%d%d",&n,&m)) { for(int i=1;i<=n;i++)scanf("%s",s[i]+1); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ss[i][j]=s[i][j]; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(!vis[i][j]&&ss[i][j]=='.') dfs(i,j); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(ss[i][j]=='?'&&!vis[i][j])s[i][j]='#'; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { ss[i][j]=s[i][j]; if(s[i][j]=='?')ss[i][j]='.'; } int cnt=deal(); if(cnt==-1)printf("Impossible\n"); else { int gg=0; for(int i=1;i<=n&&!gg;i++) for(int j=1;j<=m&&!gg;j++) if(s[i][j]=='?') { ss[i][j]='#'; int temp=deal(); if(temp==cnt-1)gg=1; ss[i][j]='.'; } if(gg)printf("Ambiguous\n"); else { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) printf("%c",ss[i][j]); printf("\n"); } } } } return 0;}
0 0
- GYM 100971 A.Treasure Island(dfs+并查集)
- Gym 100971A Treasure Island
- GYM Samara16 A Treasure Island 暴力
- cdoj island(并查集)
- GYM 101173 H.Hangar Hurdles(并查集+bfs+dfs)
- 并查集+DFS
- GYM 101128 B.Black Vienna(并查集)
- POJ - 1308 Is It A Tree?(并查集+dfs)
- SPOJ-PT07Y Is it a tree DFS/并查集
- GYM 101128 A.Promotions(dfs)
- GYM 101128 A.Promotions(dfs)
- GYM 100685 G【并查集】
- Gym 100703J 并查集
- nyoj99(并查集+欧拉路+dfs)
- uva208Firetruck(并查集 + DFS)
- HDU 5438(并查集 + dfs)
- CFgym:Treasure Island(搜索 & 思维)
- POJ1291-并查集/dfs
- python-访问字典
- 基于moment的倒计时
- vue-cli快速构建Vue项目
- Shell(一):功能、配置和插件
- 未完成
- GYM 100971 A.Treasure Island(dfs+并查集)
- TensorFlow学习笔记(二)MNIST手写数字识别
- 欢迎使用CSDN-markdown编辑器
- (转载)Java中HashMap底层实现原理(JDK1.8)源码分析
- java 日期基础操作
- 求数组中的逆序对 分治法
- Java常见异常总结
- oracle下查询某条记录的插入时间
- iOS中为tableView的section添加弧形