1. 程式人生 > >UVA—297四分樹(非二叉樹)

UVA—297四分樹(非二叉樹)

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">題意:</span>

用一個四分樹來表示一個黑白影象,方法是用根節點來表示整個影象,然後再進行等分,按照從右上角的影象開始逆時針的順序編

號,依次有四個節點,如果某子節點對應的區域是全黑或者全白,則直接用黑或者白節點來代替,如果對應的區域既有白區域,也

有黑區域,則用灰節點來表示,並且為這個區域遞迴建樹。給出兩棵四分樹的先序遍歷,求兩者合併之後(黑色部分合並),黑色

畫素的個數,其中p表示中間節點,f表示黑色,e表示白色。

下面上圖:


input:

3
ppeeefpffeefe
pefepeefe
peeef
peefe
peeef
peepefefe
output:
There are 640 black pixels.
There are 512 black pixels.
There are 384 black pixels.

分析:

由於四分樹比較特殊,沒有左右子樹之分,只有根節點和子節點的區別,所以先序遍歷就能確定整棵樹,可以借圖分析,之後只

需要寫一個遞迴建樹的函式,並且在建樹的過程中,邊建樹,變進行統計,由於是四分樹,而且根據一個根節點等同於一個區域,

將影象化為四部分,也體現出了四分樹的獨特之處,這樣就可以遞迴建樹,四次呼叫就可以完成建樹工作,至於統計,則要進行

標記,用一個字元陣列儲存輸入的字元,用一個二維陣列來作為標記陣列,統計一個標記一個,標記過得不再進行統計,這樣就

完成了。程式碼挺短的,下面上程式碼。

程式碼:

<span style="font-size:14px;">#include <bits/stdc++.h>
using namespace std;

const int len=32;
const int maxn=1024+10;
char s[maxn];
int buf[len][len],cnt;

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);
        draw(s,p,r,c,w/2);
        draw(s,p,r+w/2,c,w/2);
        draw(s,p,r+w/2,c+w/2,w/2);
    }
    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;
    cin >>t;
    while(t--)
    {
        memset(buf,0,sizeof(buf));
        cnt=0;
        for(int i=0;i<2;i++)
        {
            cin >>s;
            int p=0;
            draw(s,p,0,0,len);
        }
        printf("There are %d black pixels.\n", cnt);
    }
    return 0;
}</span>