白书 例题6-11
用四分树来表示一个黑白图像:最大的图为根,然后按照图中的方式编号,从左到右对应4个子结点。如果某子结点对应的区域全黑或者全白,则直接用一个黑结点或者白结点表示;如果既有黑又有白,则用一个灰结点表示,并且为这个区域递归建树。
思路
用一个buffer表示黑白表格,利用递归建树,每当遇见p(灰色)就往下递归四个节点,遇到f(黑色)就把buf[][]
对应的位置设为1
cuf++,找对应的位置
是个难点.需要遍历(r,r+w)(c,c+w)r,c是buf的下标,从左上角开始,w是格子的大小,初始为总len=32,每递归一层,除2
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
;
}
|