题意
给H行W列的字符矩阵,每个字符对应一个16位进制的数,转化为二进制后,1表示黑点,0表示白点,表示的文字可拉伸但不可断开,求所给矩阵表示的象形文字。
输出时每个文字对应的缩写如下
Ankh:A
Wedjat:J
Djed:D
Scarab:S
Was:W
Akeht:K
思路
刚开始完全没有思路,后来看别人题解才明白每个文字不同之处在于连通块的数目:A:0, J:3, D:5, S:4, W:0, K:2 。
先把每行每个字符转化成二进制后存在tab数组里,之后dfs
为了区别文字内的白块与文字外的白块,需要先将矩阵加一个外围,即从tab[1]开始,且每行从tab[i][1]存储;先DFS1将文字外的0全都赋值为‘*’,再DFS2每个图形里面有几个连通块。
总结
还是不会dfs,看的别人的题解写出来的,改动也不是多大。
目前所总结的dfs写法:先写上退出条件,再找到递归条件,遍历其周围的字符。
现在的状态是题解可以看明白,但是在怎么找到这个DFS的思路方面没有开窍。
TIPS:
1. map的遍历要有迭代器,用C++11的特性for (auto i : cnt) while (i.second--) cout << i.first; 这样写也可以。注意:用迭代器的时候是it->first。
2. memcpy
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <map> 5 #include <cstring> 6 #include <string> 7 const int maxn = 205; 8 using namespace std; 9 const string dict[16] = { 10 "0000", "0001", "0010", "0011", 11 "0100", "0101", "0110", "0111", 12 "1000", "1001", "1010", "1011", 13 "1100", "1101", "1110", "1111", 14 }; 15 const int dir[4][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } }; 16 const char alp[8] = { 'W', 'A', 'K', 'J', 'S', 'D' }; 17 char tab[maxn][maxn]; 18 int H, W, kase, cur; 19 20 bool isin(const int r, const int c) 21 { 22 return r >= 0 && r <= H+1 && c >= 0 && c <= W+1; 23 } 24 void dfs1(const int r, const int c) 25 { 26 if(!isin(r,c) || tab[r][c] != '0') return; 27 tab[r][c] = '*'; 28 for(int i = 0; i < 4; i++) 29 dfs1(r+dir[i][0],c+dir[i][1]); 30 } 31 void dfs2(const int r, const int c) 32 { 33 if(!isin(r,c) || tab[r][c] != '1') return; 34 tab[r][c] = '*'; 35 for(int i = 0; i < 4; i++) { 36 int dr = r+dir[i][0], dc = c + dir[i][1]; 37 if(tab[dr][dc] == '0') { 38 cur++; 39 dfs1(dr,dc); 40 } 41 else dfs2(dr,dc); 42 } 43 } 44 int main() 45 { 46 while (cin >> H >> W && (H || W)) { 47 memset(tab, '0', sizeof(tab)); 48 W *= 4; 49 for (int i = 1; i <= H; ++i){ 50 string line, res; 51 cin >> line; 52 int len = line.size(); 53 for(int i = 0; i < len; i++) 54 res += dict[line[i] >= 'a' ? (line[i] - 'a' + 10) : (line[i] - '0')]; 55 memcpy(tab[i]+1, res.c_str(), W); 56 } 57 dfs1(0,0); 58 map<char, int> cnt; 59 for(int i = 1; i <= H; i++) 60 for(int j = 1; j <= W; j++) { 61 if(tab[i][j] != '1') continue; 62 cur = 0; 63 dfs2(i,j); 64 cnt[alp[cur]]++; 65 } 66 cout << "Case " << ++kase << ": "; 67 map<char, int>::iterator it; 68 for(it = cnt.begin(); it != cnt.end(); it++) 69 while(it->second--) 70 cout << it->first; 71 cout << endl; 72 } 73 return 0; 74 }