不要受上一题的影响(uva572),此处的连通没有对角线方向。
基本思路:
1.在还原的二进制图再增加一圈0(没必要处理,只需改变一下边界)。
2.将最外圈的0以及与最外圈的0相连通的0赋值为-1(可以是非0非1的任何数,此处只是做标记)。
3.按照1的连通块找里面的0(同时将找过的1标记为-1),找到0即是里面的一个”洞“,并将这个”洞“用-1标记。
4.将一个完整的1的连通块找完后,看有多少个”洞“,即为哪个图形。
5.循环步骤3、4,直到找完。
样例输入:
5 5
fffff
0f0f0
fffff
0f0f0
fffff
二进制图(加上外圈0)
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=200+10;
int pic[maxn][maxn];
int m,n;
int circle;
int sixteen[16][4]=
{{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},
{0,1,0,0},{0,1,0,1},{0,1,1,0},{0,1,1,1},
{1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1},
{1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1}
};
void DFS0(int i,int j) //此递归有两个用处:1.标记最外层0 2.填“洞”
{
if(i>m+1||i<0||j>n+1||j<0||pic[i][j]!=0) //外圈0
return;
pic[i][j]=-1;
DFS0(i-1,j);
DFS0(i+1,j);
DFS0(i,j-1);
DFS0(i,j+1);
}
void DFS1(int i,int j) //按照1的连通块寻找“洞”
{
if(i>m+1||i<0||j>n+1||j<0||pic[i][j]==-1) //外圈0
return;
if(pic[i][j]==0)
{
::circle++;
DFS0(i,j);
return;
}
pic[i][j]=-1;
DFS1(i-1,j);
DFS1(i+1,j);
DFS1(i,j-1);
DFS1(i,j+1);
}
int main()
{
char ch[maxn];
int K=0;
while(scanf("%d %d",&m,&n)==2&&m&&n)
{
int sum[6]={0,0,0,0,0,0};
memset(pic,0,sizeof(pic)); //别忘初始化
for(int i=1;i<=m;i++) //从1开始空出外圈一行0
{
int h=1;
scanf("%s",ch);
for(int j=0;j<n;j++)
{
int num;
if(ch[j]>='a'&&ch[j]<='z')
num=ch[j]-87;
else num=ch[j]-48;
pic[i][h++]=sixteen[num][0];
pic[i][h++]=sixteen[num][1];
pic[i][h++]=sixteen[num][2];
pic[i][h++]=sixteen[num][3];
}
}
n=n*4;
// for(int i=0;i<=m+1;i++)
// {
// for(int j=0;j<=n+1;j++)
// cout<<pic[i][j]<<" ";
// cout<<endl;
// }
DFS0(0,0);
for(int i=1;i<=m;i++) //只需判断还原的二进制图
for(int j=1;j<=n;j++)
if(pic[i][j]==1)
{
::circle=0;
DFS1(i,j);
sum[circle]++;
}
cout<<"Case "<<++K<<": ";
if(sum[1]!=0)
for(int i=0;i<sum[1];i++)
cout<<'A';
if(sum[5]!=0)
for(int i=0;i<sum[5];i++)
cout<<'D';
if(sum[3]!=0)
for(int i=0;i<sum[3];i++)
cout<<'J';
if(sum[2]!=0)
for(int i=0;i<sum[2];i++)
cout<<'K';
if(sum[4]!=0)
for(int i=0;i<sum[4];i++)
cout<<'S';
if(sum[0]!=0)
for(int i=0;i<sum[0];i++)
cout<<'W';
cout<<endl;
}
return 0;
}