/* 代码虽然极其简短,但看懂也是不易,我觉得自己就思考了挺久,才彻底弄懂。所以做好心理准备,不要因为它似乎简短就轻视它,多多揣摩一下!~ 四分树比较特殊,只需给出先序遍历就能确定整棵树(因为每棵树的每个子节点,都会分出4个节点,也即4个字母,除非递归走到叶子节点。当然,还除非都是同色,那该子树就只用1个字母表示了) 所以只需要编写一个"画出来的"过程,边画边统计即可 */
#include <cstdio> #include <cstring> const int len = 32; const int maxn = 1024 + 10; char s[maxn]; int buf[len][len], cnt; //把字符串 s[p...]导出到以 (r, c) 为左上角,变长为w的缓冲区中 //2 1 //3 4 void draw(const char *s, int &p, int r, int c, int w) { char ch = s[p++]; if (ch == 'p') { draw(s, p, r , c+w/2, w/2); //1 draw(s, p, r , c , w/2); //2 draw(s, p, r+w/2, c , w/2); //3 draw(s, p, r+w/2, c+w/2, w/2); //4 } else if (ch == 'f') //画黑像素(白像素不画) { for (int i = r; i < r + w; i++) for (int j = c; j < c + w; j++) if (buf[i][j] == 0) { buf[i][j] = 1; cnt++; } } } //(r, c)是(row, col)的简写,表示左上角的坐标(“其实严格意义上来说,并不是坐标,而是下标,亦即在把它当作二维数组时,它的两个下标依次是 r, c”) //所以,先表示左上角所在行,再表示左上角所在列。刚开始我理解错误,将其理解为笛卡尔系下的坐标平面,就觉得这些代码,怎么看怎么不对劲,后来顿悟了,是我理解错了(r, c)的意义 int main() { int T; scanf("%d", &T); while (T--) { memset(buf, 0, sizeof(buf)); cnt = 0; for (int i = 0; i < 2; i++) { scanf("%s", &s); int p = 0; draw(s, p, 0, 0, len); } printf("There are %d black pixels. ", cnt); } return 0; }