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;}
原创粉丝点击