Uva297 Quadtrees【递归建四分树】【例题6-11】

时间:2022-12-04 10:00:12

白书 例题6-11

用四分树来表示一个黑白图像:最大的图为根,然后按照图中的方式编号,从左到右对应4个子结点。如果某子结点对应的区域全黑或者全白,则直接用一个黑结点或者白结点表示;如果既有黑又有白,则用一个灰结点表示,并且为这个区域递归建树。

Uva297 Quadtrees【递归建四分树】【例题6-11】

思路

用一个buffer表示黑白表格,利用递归建树,每当遇见p(灰色)就往下递归四个节点,遇到f(黑色)就把buf[][]对应的位置设为1 cuf++,找对应的位置是个难点.需要遍历(r,r+w)(c,c+w)r,c是buf的下标,从左上角开始,w是格子的大小,初始为总len=32,每递归一层,除2

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include
"cstdio"
#include
"cstring"
#include
"iostream"
#include
"cmath"
#include
"cstring"
#include
"cstring"
#include
"cstdio"
 
#pragma
warning(disable:4996)
 
const
int
len
=
32;//边长
const
int
maxn
=
1024
+
10;
char
s[maxn];
int
buf[len][len],
cnt;//指针
//
s是读入的字符串序列,p当前正在读的字符串的下标,r是纵坐标,c是横坐标,w是当前块的大小,从len开始,深度+1,w/=2.
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++;//黑块计数
                }
            }
        }
    }
}
 
int
main()
{
    int
T;
    scanf("%d",
&T);
    while
(T--)
{
        memset(buf,
0,
sizeof(buf));
        cnt
=
0;
        for
(int
i
=
0;
i
<
2;
i++)
{//读取两棵树,操作同一个buf,达到合并的目的
            scanf("%s",
s);
            int
p
=
0;
            draw(s,
p,
0,
0,
len);
        }
        printf("%d",
cnt);
    }
 
 
 
    return
0;
}