POJ 1610 Quad Trees

又是一週數算實習,馬上就要上機考試了整個都要不好了,還好這一次的四分樹作業給了我一丟丟的信心…

作業是禁止使用STL的,而且明確要求必須用空間數據結構,所以這道題本來可以用廣搜寫的很簡單,但是爲了滿足作業需求我還是使用了四分樹,並且用數組模擬了隊列進行廣搜,直接用隊列廣搜會有更好的效果。

總體思路就是根據每個區塊的特點去建立一個四分樹,四分樹的每個結點就代表這一個區塊的特性,如果state1的值爲1,就意味着這個區塊裏面的數字既有1又有0,如果state1的值爲0,那麼這個區塊裏面所有的值都是一樣的,並且這個值記錄在state2裏面。

用遞歸的方法建樹,每次都判斷自己這個區塊是不是既有0又有1,如果是,那麼分成四塊繼續計算,如果不是,直接state1的值變爲0並且停止遞歸。

廣搜的時候用數組模擬了隊列,應該也沒什麼好多說的。在我的這個代碼中重複編碼的地方還是太多了,如果能把某個節點的四個指針放在一個指針數組裏面,這樣遍歷或者初始化的時候能夠方便很多,不過我也懶得修改了,就當提供一個思路。

再就是scan函數使用來前序遍歷整個樹來判斷樹有沒有寫對的,對整個程序沒有影響,在遍歷的時候我採用的是ACBD的順序遍歷結點,主要是因爲我定義的xy和題目中的反過來了= =

#include<iostream>
#include<cstdio>
#include<memory.h>
using namespace std;

#define maxn 520

bool map[maxn][maxn]={0};
bool output[4*maxn*maxn]={0};
int result[maxn]={0};

struct area{
    int x1,y1,x2,y2;
};

struct node{
    area a;
    node *A, *B, *C, *D;
    int state1;
    int state2;
};

node* queue[4*maxn*maxn]={0};

void build(node* root){

    bool one = 0, zero = 0;
    area temp = root->a;

    //cout<<"("<<temp.x1<<","<<temp.y1<<")"<<"("<<temp.x2<<","<<temp.y2<<")"<<endl;

    for(int i=temp.x1;i<temp.x2;++i){
        for(int j=temp.y1;j<temp.y2;++j){
            if(map[i][j])
                one = 1;
            else
                zero = 1;

            if(one&&zero)
                break;
        }
        if(one&&zero)
            break;
    }

    if(one&&zero){
        root->state1 = 1;

        int midx = (temp.x1 + temp.x2)>>1;
        int midy = (temp.y1 + temp.y2)>>1;
        //printf("x1: %d x2: %d\n",temp.x1,temp.x2);
        //printf("midx: %d midy: %d\n",midx,midy);

        root->A = new node;
        root->B = new node;
        root->C = new node;
        root->D = new node;

        root->A->A = root->A->B = root->A->C = root->A->D = NULL;
        root->B->A = root->B->B = root->B->C = root->B->D = NULL;
        root->C->A = root->C->B = root->C->C = root->C->D = NULL;
        root->D->A = root->D->B = root->D->C = root->D->D = NULL;

        int x1 = temp.x1,x2 = temp.x2,y1 =temp.y1, y2 =temp.y2;

        (root->A->a).x1 = x1; (root->A->a).y1 = y1; (root->A->a).x2 = midx; (root->A->a).y2 = midy;
        build(root->A);

        (root->B->a).x1 = midx; (root->B->a).y1 = y1; (root->B->a).x2 = x2; (root->B->a).y2 = midy;
        build(root->B);

        (root->C->a).x1 = x1; (root->C->a).y1 = midy; (root->C->a).x2 = midx; (root->C->a).y2 = y2;
        build(root->C);

        (root->D->a).x1 = midx; (root->D->a).y1 = midy; (root->D->a).x2 = x2; (root->D->a).y2 = y2;
        build(root->D);

        return;
    }
    else{
        root->state1 = 0;
        root->state2 = one;
    }
    return;
}

int BFS(node *root){
    int start = 0,end = 0;
    int ocount = 0;
    queue[start] = root;
    end++;
    while(start<end){
        //cout<<ocount<<endl;
        node* temp = queue[start++];

        if(temp->state1){
            output[ocount++] = 1;
        }
        else{
            output[ocount++] = 0;
            output[ocount++] = temp->state2;
        }

        if(temp->A)
            queue[end++] = temp->A;
        if(temp->C)
            queue[end++] = temp->C;
        if(temp->B)
            queue[end++] = temp->B;
        if(temp->D)
            queue[end++] = temp->D;
    }
    return ocount;
}

void scan(node* root){
    if(!root)
        return;
    if(root->state1){
        printf("(1) ");
    }
    else{
        printf("(0,%d) ",root->state2);
    }
    scan(root->A);
    scan(root->C);
    scan(root->B);
    scan(root->D);
    return;
}

void trans(int n){
    int overload = n%4;
    int recount = 0;
    int t = 0;
    for(int i=overload - 1;i>=0;--i){
        t += output[i]<<(overload-i-1);
    }
    result[recount++] = t;

    int total = n/4;
    //cout<<"total: "<<total<<endl;
    for(int i=0;i<total;++i){
        int start = overload + i*4;

        /*for(int j=0;j<4;++j)
            printf("%d ",output[j+overload]);
        printf("\n");*/

        int t = 0;
        for(int j=0 ;j < 4;++j){
            t+=output[j+start]<<(3-j);
        }
        result[recount++] = t;
    }

    for(int i=0;i<=total;++i)
        printf("%X",result[i]);
    printf("\n");
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        memset(map,0,sizeof(map));

        int n;
        scanf("%d",&n); 

        for(int i=0;i<n;++i){
            for(int j=0;j<n;++j){
                scanf("%d",&map[i][j]);
            }
        }

        node *root = new node;
        (root->a).x1 = 0;
        (root->a).y1 = 0;
        (root->a).x2 = n;
        (root->a).y2 = n;
        root->state1 = root->state2 = 0;
        root->A = root->B = root->C = root->D = NULL;

        build(root);
        int total = BFS(root);

        trans(total);

    }
    //system("pause");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章