#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;
const int maxh=200+10;
const int maxw=50*4+10;
char bin[256][5];//映射:將一個十六進制數字映射成四個二進制數字 (字符類型 轉換int要減去'0')
int pic[maxh][maxw],H,W,color[maxh][maxw];
char line[maxw];//類型爲char
void decode(char ch,int row,int col){
for(int i=0;i<4;i++){
pic[row][col+i]=bin[ch][i]-'0';//不要忘記-'0'
}
}
const int dr[]={0,0,1,-1};
const int dc[]={-1,1,0,0};
void dfs(int row,int col,int c){
color[row][col]=c;
for(int i=0;i<4;i++){
int row2=row+dr[i];
int col2=col+dc[i];
if(row2>=0&&row2<H&&col2>=0&&col2<W&&pic[row2][col2]==pic[row][col]&&color[row2][col2]==0)
//在邊界內 且屬於相同類型 且未塗色
dfs(row2,col2,c);
}
}
vector<set<int> > neighbors;
void check_neighbors(int row,int col){
for(int i=0;i<4;i++){
int row2=row+dr[i];
int col2=col+dc[i];
if(row2>=0&&row2<H&&col2>=0&&col2<W&&color[row2][col2]!=1&&pic[row2][col2]!=1)
//講在邊界內 且不是背景 且不是輪廓 的方塊顏色加入相應字符顏色編號的顏色集合中
neighbors[color[row][col]].insert(color[row2][col2]);
}
}
//將不同象形字輪廓的顏色編號轉換到對應象形字編號
const char* code="WAKJSD";
char recognize(int c){
int cnt=neighbors[c].size();
return code[cnt];
}
int main(){
strcpy(bin['0'],"0000");
strcpy(bin['1'],"0001");
strcpy(bin['2'],"0010");
strcpy(bin['3'],"0011");
strcpy(bin['4'],"0100");
strcpy(bin['5'],"0101");
strcpy(bin['6'],"0110");
strcpy(bin['7'],"0111");
strcpy(bin['8'],"1000");
strcpy(bin['9'],"1001");
strcpy(bin['a'],"1010");
strcpy(bin['b'],"1011");
strcpy(bin['c'],"1100");
strcpy(bin['d'],"1101");
strcpy(bin['e'],"1110");
strcpy(bin['f'],"1111");
int kase=0;
while(cin>>H>>W&&H){
memset(pic,0,sizeof(pic));
for(int i=0;i<H;i++){
cin>>line;
for(int j=0;j<W;j++){
decode(line[j],i+1,j*4+1);
}
}
H+=2; //上下左右各增一行空白邊界 空白邊界顏色爲1 因爲dfs從(0,0)開始 初始cnt爲1
//即字母背景色爲1
W=W*4+2;
int cnt=0;
vector<int> cc;//存放pic=1的顏色值 即不同象形字輪廓的顏色值 不同輪廓對應一個不同的顏色值
memset(color,0,sizeof(color));
for(int i=0;i<H;i++){
for(int j=0;j<W;j++){
if(!color[i][j]){//選取未塗色連通塊
dfs(i,j,++cnt);
if(pic[i][j]==1)
cc.push_back(cnt);
}
}
}
neighbors.clear();
neighbors.resize(cnt+1);
for(int i=0;i<H;i++){
for(int j=0;j<W;j++){
if(pic[i][j]==1)
check_neighbors(i,j);
}
}
vector<char> ans;
for(int i=0;i<cc.size();i++)
ans.push_back(recognize(cc[i]));
sort(ans.begin(),ans.end());
printf("Case %d: ",++kase);
for(int i=0;i<ans.size();i++) printf("%c",ans[i]);
cout<<endl;
}
return 0;
}
入門經典-6.4圖-163-uva1103古代象形符號-四連塊,DFS,種子填充,圖像識別⭐⭐⭐⭐⭐複雜度:4
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.