Gym
来源:互联网 发布:淘宝下单微信全额返现 编辑:程序博客网 时间:2024/05/16 06:42
http://codeforces.com/gym/100971/problem/A
比赛中第一眼就看到这个了,当时以为是简单的搜索就完事了,后来发现还得枚举情况,就想了三种特判的条件,分别把模糊的地方当做陆地和海洋处理,如果都是1 那么就是ambiguous。
如果都大于1或者都等于0 肯定是不可以的。impossible.
其他情况哪个等于1 就置换哪个。
思路是没错的。
错误在搜索的地方,我开始在搜索判断小岛数量,只判断.的情况,因为’.’是合法的陆地。但是这样当两个问号相连时就出错了。比如
“####”
“.??.”
“####”
“####”
” 就会出现 impossible。
但其实是可以的。。所以搜索时把?号也给搜索了就好了。
ps:开始以为是壮压来着,因为m,n都是很小的数字。。
并且每个??号都有可能是?和#.所以要枚举好多种情况哦
错就错在不用枚举情况的,为什么呢,如果把他们都成#,那么显然是错的。,那为什么当做.会是对的呢。
因为 都当成 . ,如果是出现两个岛屿的情况,会被条件pass。
而在一个岛屿内,你如果不是当前要判断的那个地方,你当成.和#和当前好想没啥关系啊。。
#include <iostream>#include <cstdio>#include <cstdlib>using namespace std;const int maxn=200;char a[maxn][maxn];char b[maxn][maxn];int m,n;int fx[4][2]={{1,0},{-1,0},{0,1},{0,-1}};int dfs1(int a1,int b1){ if(a1>m||a1<1||b1>n||b1<1) return 0; if(b[a1][b1]=='#') return 0; b[a1][b1]='#'; for(int i=0;i<4;i++) { int xx=a1+fx[i][0]; int yy=b1+fx[i][1]; if(b[xx][yy]=='.') dfs1(xx,yy); } return 0;}int dfs(){ int sum=0; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) b[i][j]=a[i][j]; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) if(b[i][j]=='.') { sum++; dfs1(i,j); } return sum;}int main(){ cin>>m>>n; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) cin>>a[i][j]; bool flag=false; bool qq=false; bool ss=false; for(int i=1;i<=m;i++) {for(int j=1;j<=n;j++) { if(a[i][j]=='?') {a[i][j]='.'; int sum1=dfs(); a[i][j]='#'; int sum2=dfs(); if(sum1==1&&sum2==1){flag=true;break;} else if(sum1>1&&sum2>1) {qq=true;break;} else if(sum1==0&&sum2==0) {ss=true;break;} else { if(sum1==1) a[i][j]='.'; else a[i][j]='#'; } } } if(flag||qq||ss) break; } if(flag) puts("Ambiguous"); else if(qq) puts("Impossible"); else if(ss) puts("Impossible"); else { for(int i=1;i<=m;i++) {for(int j=1;j<=n;j++) printf("%c",a[i][j]); printf("\n"); } } return 0;}
‘看了别人的代码,比我的更好理解。。
他是通过判断数量来推断的。
不成立的条件就是存在两个.. 可以直接除去
存在ambigous的情况是当一个地方的改变不影响连通度(只改变一个当然正常,若是改变很多就是说明这个点是桥。是不能改变的。)
其他情况就正常输出。
这道题和我卡的数据都不一样,错误在于判断相等后(相等就是说这个问号没在大陆里),可以直接跳出的
没有.的话,
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;/*看了别人的代码,和我判断的方式不一样,他是通过判断陆地的大小,来区分的。我感觉我写得好,因为我不太擅长计数相关。*/const int maxn=200;int fx[4][2]={{1,0},{-1,0},{0,1},{0,-1}};bool vis[maxn][maxn];int all;int m,n;int b[maxn][maxn];char a[maxn][maxn];int sum;int dfs(int a1,int b1){ if(a1<1||a1>m||b1>n||b1<1) return 0; sum++; vis[a1][b1]=true; for(int i=0;i<4;i++) { int xx=a1+fx[i][0]; int yy=b1+fx[i][1]; if(!vis[xx][yy]&&b[xx][yy]) dfs(xx,yy); } return 0;}int main(){ int k1,k2; memset(vis,false,sizeof(vis)); cin>>m>>n; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) {cin>>a[i][j]; if(a[i][j]=='.') {b[i][j]=1;k1=i;k2=j;} else if(a[i][j]=='?') b[i][j]=2; } int s=0; memset(vis,false,sizeof(vis)); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) { if(b[i][j]==1&&!vis[i][j]) {sum=0; dfs(i,j); s++;} } bool flag=false; if(s>1) { puts("Impossible");return 0; } else { int all=sum; for(int i=1;i<=m&&!flag;i++) for(int j=1;j<=n&&!flag;j++) { if(b[i][j]==2) {b[i][j]=0; sum=0; memset(vis,false,sizeof(vis)); dfs(k1,k2); //cout<<sum<<endl; if(sum==all) continue; if(sum==all-1){flag=true;break;} else b[i][j]=1;} } } if(flag) puts("Ambiguous"); else { for(int i=1;i<=m;i++) {for(int j=1;j<=n;j++) { if(b[i][j]) cout<<'.'; else if(b[i][j]==0) cout<<'#'; } cout<<endl; } } return 0;}
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- 链表学习(5)
- Matisse——Android 图片/视频选择器
- POJ 2186 Popular Cows 强连通分量(Kosaraju)
- 程序猿学习第三天,框架和表单
- Android 拖拽ViewDragHelper解析 自定义ViewGroup神器
- Gym
- 咖啡
- HCNA学习笔记(五)ICMP协议
- /etc/fstab 文件解释
- 最大子矩阵和
- 中医穴位
- Js之Navigator对象
- 对110W知乎用户信息进行分析,使用echarts+servlet+jsp可视化展示
- javascript运行机制