题意:给你一张图, 输出图里包涵的图形。
题目给出的图所围成的连通的白色块是不一样的,根据这个来判断
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#include<set>
#include<stack>
#define cl(a,b) memset(a,b,sizeof(a));
#define LL long long
#define P pair<int,int>
#define X first
#define Y second
#define out(x) cout<<x<<endl;
using namespace std;
const int maxn=950;
const int inf=9999999;
char convers[16][5]={"0000","0001","0010","0011","0100",
"0101","0110","0111","1000","1001","1010","1011",
"1100","1101","1110","1111"};
char tu[]="WAKJSD";
int n,m;
int dir[][2]={{0,1},{1,0},{-1,0},{0,-1}};
char a[maxn][maxn];//输入的图转化为01二进制构成的图
char tmp[maxn];
char myans[maxn];
int color[maxn][maxn];//每个点的标志颜色
bool vis[maxn][maxn];//访问标记
void bfs_color(int x,int y,int num,char aim){
//外围的白色编号-1,被黑色围住的白色部分从-2开始编号,黑色图案从1开始依次编号
queue<P> q;
q.push(P(x,y));
vis[x][y]=true;
color[x][y]=num;
while(!q.empty()){
P tmp=q.front();q.pop();
for(int i=0;i<4;i++){
P s=tmp;
int xx=s.X+dir[i][0];
int yy=s.Y+dir[i][1];
if(xx<0||xx>n||yy<0||yy>m||vis[xx][yy]||a[xx][yy]!=aim)continue;
vis[xx][yy]=true;
color[xx][yy]=num;
q.push(P(xx,yy));
}
}
}
bool used[maxn][maxn];
int bfs(int x,int y,int num){
set<int> myset;
queue<P> q;
q.push(P(x,y));
used[x][y]=true;
while(!q.empty()){
P tmp=q.front();q.pop();
for(int i=0;i<4;i++){
P s=tmp;
s.X+=dir[i][0];
s.Y+=dir[i][1];
if(s.X<0||s.X>n||s.Y<0||s.Y>m||used[s.X][s.Y])continue;
if(a[s.X][s.Y]=='1'&&color[s.X][s.Y]==num){
used[s.X][s.Y]=true;
q.push(s);
}
else if(a[s.X][s.Y]=='0'&&color[s.X][s.Y]<=-2){
myset.insert(color[s.X][s.Y]);
}
}
}
return myset.size();
}
int main(){
int cas=1;
while(~scanf("%d%d",&n,&m)&&(n||m)){
cl(a,'\0');//在图的周围加上一圈,便于下面的计数
for(int i=0;i<=n+1;i++)a[i][0]=a[i][m*4+1]='0';
for(int i=0;i<=m*4+1;i++)a[0][i]=a[n+1][i]='0';
for(int i=1;i<=n;i++){
scanf("%s",tmp);
for(int j=0;j<m;j++){
if(tmp[j]>='0'&&tmp[j]<='9'){
int index=tmp[j]-'0';
strcat(a[i],convers[index]);
}
else {
int index=tmp[j]-'a'+10;
strcat(a[i],convers[index]);
}
}
}
for(int i=0;i<=n+1;i++)a[i][0]=a[i][m*4+1]='0';
for(int i=0;i<=m*4+1;i++)a[0][i]=a[n+1][i]='0';
m*=4;m+=1;n+=1;
cl(color,0);
cl(vis,false);
bfs_color(0,0,-1,'0');//外围的0染成-1,区别于被黑色包围的内部的白色块
int num=1;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++)if(a[i][j]=='1'&&!vis[i][j]){
bfs_color(i,j,num,'1');num++;//黑色块的编号
}
}
int num2=-2;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++)if(a[i][j]=='0'&&!vis[i][j]){
bfs_color(i,j,num2,'0');num2--;//黑色包涵的白色块编号
}
}
cl(used,false);
int t=0;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++)if(!used[i][j]&&color[i][j]>=1){
int x=bfs(i,j,color[i][j]);//搜出黑色块里的白色块个数
myans[t++]=tu[x];
}
}
myans[t]='\0';
sort(myans,myans+t);
printf("Case %d: %s\n",cas++,myans);
}
return 0;
}
/*
3 2
ff
f0
ff
*/