1. 程式人生 > >UVA297:Quadtrees(四分樹)

UVA297:Quadtrees(四分樹)

sam 數組 while 規則 bool put http truct mage

題目描述

四象樹是每個內結點均有4個子結點的特殊四叉樹,它可用於描述平面上黑白圖像。平面上的黑白圖像是32行×32列的正方形,每個格子稱為1個象素,是最小的圖像單位。正方形圖像可分成四個相等的小正方形,可按直角坐標系四個象限的順序分別編號1,2,3,4,分別對應於四象樹的四個子結點。這樣,32行×32列的圖像就對應於一棵深度為6的完全四叉樹,最底層的每個葉結點正好對應於一個象素。但我們可以壓縮四象樹的結點數量。

當圖像上某個區域為全白或者全黑時,可把該區域在四象樹上對應的結點描述為全白(用小寫字母e表示)或者全黑(用小寫字母f表示),並且對這樣的結點不再擴展子結點,因為再擴展出的子樹上每個結點都是相同的顏色。

只有當圖像上某個區域為“雜色”時,才繼續劃分成四個子區域(在四象樹上對應的結點用小寫字母p表示),然後“純”色的子區域也不再擴展,並繼續擴展“雜”色子區域。例如,下圖左、中兩個圖像可分別用它們下邊的四象樹描述。

技術分享圖片

技術分享圖片

我們感興趣的問題是:當兩個大小均為32*32的黑白圖像疊加後,合成的新圖像是什麽樣子。合成的規則是:當一個圖像上某個區域為全黑時,新圖像的這個區域即為全黑;當一個圖像上某個區域為全白時,新圖像的這個區域的顏色是另加一個圖像上這個區域的顏色。上圖準確地示例了本合成的規則。

我們給出兩個圖像對應四象樹的先序遍歷順序,求合成後的圖像中,黑色象素點的數量。

輸入

多組測試數據,第1行一個整數T,表示測試數據的組數,每組數據的格式為:

第1行:一個字符串,描述第1棵四象樹的先序序列

第2行:一個字符串,描述第2棵四旬樹的先序序列

輸出

對每組數據,在單獨一行上輸出一個整數,表示合成後的圖像上黑色象素的數量,格式如輸出樣例所示:

樣例輸入

3
ppeeefpffeefe pefepeefe peeef peefe peeef peepefefe

樣例輸出

There are 640 black pixels.
There are 512 black pixels.
There are 384 black pixels.

我直接把BZOJ的翻譯粘過來了(逃

思路1:數據量很小。我第一次寫時直接模擬了兩棵四叉樹的建樹與搜索,然後捎帶著把最後的黑色個數算出來了。其中黑色結點的值跟它的深度有關,寫一寫就能找到規律。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <cmath>
 5 using namespace std;
 6 
 7 struct node
 8 {
 9     char c;
10     node *ptr[4];
11     node(){for (int i = 0; i < 4; i++)    ptr[i] = NULL;}
12 };
13 
14 node *root1, *root2;
15 
16 int sum, cnt;//sum是最終結果,cnt是記錄字符串走到哪個位置了
17 
18 void release(node *root)//釋放
19 {
20     if (!root)    return;
21     for (int i = 0; i < 4; i++)
22         release(root->ptr[i]);
23     delete root;
24 }
25 
26 void build(string cur, node *&root)//建樹,記得root要加地址符
27 {
28     root = new node();
29     root->c = cur[cnt++];
30     if (root->c == p)
31         for (int i = 0; i < 4; ++i)
32         {
33             root->ptr[i] = new node();
34             build(cur, root->ptr[i]);
35         }
36 }
37 
38 void dfs(node *root1, node *root2, int depth)
39 {
40     //大概分了三種情況討論
41     if (root1->c == f || root2->c == f)//有一個是黑
42     {
43         sum += pow(4,6-depth);//數學可推……
44         return;
45     }
46     else if (root1->c == e && root2->c == e)//全是白
47         return;
48     //對於‘p‘的點深搜
49     bool flag1 = root1->c==p, flag2 = root2->c==p;
50     node *x = root1, *y = root2;
51     for (int i = 0; i < 4; i++)
52     {
53         if (flag1)    x = root1->ptr[i];
54         if (flag2)    y = root2->ptr[i];
55         dfs(x, y, depth+1);
56     }
57 }
58 
59 int main()
60 {
61     int test;
62     scanf("%d", &test);
63 
64     while (test--)
65     {
66         sum = 0;
67         string s,t;
68         cin >> s >> t;
69         cnt = 0, build(s, root1);
70         cnt = 0, build(t, root2);
71 
72         dfs(root1, root2, 1);
73 
74         printf("There are %d black pixels.\n", sum);
75 
76         release(root1),release(root2);
77     }
78 
79     return 0;
80 }

思路2:書上代碼思路是在32*32的正方形裏面塗色然後查找,貌似跟樹也沒什麽關系了……書中的註釋已經很明白了,見代碼。(PS:UVA有毒)

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 const int len = 32;
 5 const int maxn = 1024 + 10;
 6 //下面這個char數組和int變量定義順序變一下UVA居然會WA啊!
 7 //我從未見過如此厚顏無恥之OJ
 8 char s[maxn];
 9 int buf[len][len], cnt;
10 
11 //把字符串s[p..]導出到以(r,c)為左上角,邊長為w的緩沖區中
12 //2 1
13 //3 4
14 void draw(const char* s, int& p, int r, int c, int w)
15 {
16     char ch = s[p++];
17     if (ch == p)
18     {
19         draw(s, p, r    , c+w/2, w/2);//1
20         draw(s, p, r    , c    , w/2);//2
21         draw(s, p, r+w/2, c    , w/2);//3
22         draw(s, p, r+w/2, c+w/2, w/2);//4
23     }
24     else if (ch == f)
25         for (int i = r; i < r+w; i++)
26             for (int j = c; j < c+w; j++)
27                 if (buf[i][j] == 0)
28                     buf[i][j] = 1,cnt++;
29 }
30 
31 int main()
32 {
33     int t;
34     scanf("%d", &t);
35 
36     while (t--)
37     {
38         memset(buf, 0, sizeof(buf));
39         cnt = 0;
40         for (int i = 0; i < 2; i++)
41         {
42             scanf("%s",s);
43             int p = 0;
44             draw(s, p, 0, 0, len);
45         }
46                     
47         printf("There are %d black pixels.\n", cnt);
48 
49     }
50 
51     return 0;
52 }

UVA297:Quadtrees(四分樹)