剣指OFFERの木のサブ構造(九度OJ 1520)

15998 ワード

タイトルの説明:


2本のツリーA,Bを入力し,BがAのサブ構造であるか否かを判断する.
 
入力:
入力には複数のテストサンプルが含まれ、入力はEOFで終了します.各テストケースについて、入力する1行目の整数n,m(1<=n<=1000,1<=m<=1000):nは入力するツリーAのノード数(ノード1からカウント)を表し、mは入力するツリーBのノード数(ノード1からカウント)を表す.次の行にはn個の数があり、各数はAツリーのi番目の要素の数値を表し、次にn行があり、最初の数Kiはi番目のノードの子の数を表し、次にKi個の木があり、ノードiの子ノードの番号を表す.次のm+1行は、ツリーAの説明と同じである.
 
出力:
各テストケースに対応して、BがAのサブツリー出力「YES」である場合(引用符を含まない).そうでない場合は、「NO」を出力します(引用符は含まれません).
 
サンプル入力:
7 3

8 8 7 9 2 4 7

2 2 3

2 4 5

0

0

2 6 7

0

0

8 9 2

2 2 3

0

0



1 1

2

0

3

0

 
サンプル出力:
YES

NO

 
ヒント:
B 。

問題解決の考え方:


この問題には穴があり,まず問題はnとmの範囲が0ではないことを要求するが,試験例では3番目と4番目がそれぞれ1番目の木空と2番目の数空の特殊な場合である可能性がある.したがって、ここでは、scanf("%d%d",&n,&m)のときにmnに制限された範囲に注意する.
また、使用例では、単一の葉が与えられていない場合、1と入力すると、1つのノードしかなく、左サブツリーノードであることに注意してください.
例えば子供が1人しかいない場合に入力したのは
  
   

 
また、このテーマの主な考えです.まず私たちが採用したのは依然として前回のテーマで使用した構造の木で、主な思想は左のこの木の要素がなくて、右の木と比較することです.違う場合は、左の子供ノードを比較します.すべての木を巡るまで.
比較を行う場合,右側の木が空であるか,左の判断頂点が空であるかを判断し,比較の要素が異なることが発見されると,比較に失敗したことを証明する.
主なコードは、本のコードを真似て行い、自分で書いた総出BUG、あれ.
int testForCompare(TreeArr *t1,int t1i,TreeArr *t2){

    int result = 0;

    if(t1i != 0 && t2->arr[0].num != 0){

        if(t1->arr[t1i].num == t2->arr[1].num)

            result = compare(t1,t1i,t2,1);

        if(!result)

            result = testForCompare(t1,t1->arr[t1i].lchild,t2);

        if(!result)

            result = testForCompare(t1,t1->arr[t1i].rchild,t2);

    }

    return result;

};

int compare(TreeArr *t1,int t1i,TreeArr *t2,int t2i){

    if(t2i == 0)

        return 1;

    if(t1i == 0)

        return 0;

    if(t1->arr[t1i].num != t2->arr[t2i].num)

        return 0;

    return compare(t1,t1->arr[t1i].lchild,t2,t2->arr[t2i].lchild)&&compare(t1,t1->arr[t1i].rchild,t2,t2->arr[t2i].rchild);

}

すべてのコード:

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 1005

typedef struct treeelement{

    int num;

    int lchild;

    int rchild;

}TreeElement;

typedef struct treearr{

    TreeElement arr[MAXSIZE];

}TreeArr;

int testForCompare(TreeArr *t1,int t1i,TreeArr *t2);

int compare(TreeArr *t1,int t1i,TreeArr *t2,int t2i);

int main(void){

    int n,m,i,nchild,n1,n2;

    TreeArr *t1 = (TreeArr *)malloc(sizeof(TreeArr));

    TreeArr *t2 = (TreeArr *)malloc(sizeof(TreeArr));

    while(scanf("%d %d",&n,&m) != EOF){

        //....initialize the tree

        for(i=0;i<1000;i++){

            t1->arr[i].num = 0;

            t1->arr[i].lchild = 0;

            t1->arr[i].rchild = 0;

 

            t2->arr[i].num = 0;

            t2->arr[i].lchild = 0;

            t2->arr[i].rchild = 0;

        }

        t1->arr[0].num = n;

        t2->arr[0].num = m;

        //.....input the first tree

        for(i=1;i<=n;i++){

            scanf("%d",&t1->arr[i].num);

        }

        for(i=1;i<=n;i++){

            scanf("%d",&nchild);

            if(nchild == 2){

                scanf("%d %d",&n1,&n2);

                t1->arr[i].lchild = n1;

                t1->arr[i].rchild = n2;

            }else if(nchild == 1){//

                scanf("%d",&n1);

                t1->arr[i].lchild = n1;

            }else if(nchild == 0){

                 

            }

        }

        //........input the second tree

        for(i=1;i<=m;i++){

            scanf("%d",&t2->arr[i].num);

        }

        for(i=1;i<=m;i++){

            scanf("%d",&nchild);

            if(nchild == 2){

                scanf("%d %d",&n1,&n2);

                t2->arr[i].lchild = n1;

                t2->arr[i].rchild = n2;

            }else if(nchild == 1){//

                scanf("%d",&n1);

                t2->arr[i].lchild = n1;

            }else if(nchild == 0){

            }

        }

        //testing for compare

        if(testForCompare(t1,1,t2))

            printf("YES
"); else printf("NO
"); } return 0; }; int testForCompare(TreeArr *t1,int t1i,TreeArr *t2){ int result = 0; if(t1i != 0 && t2->arr[0].num != 0){ if(t1->arr[t1i].num == t2->arr[1].num) result = compare(t1,t1i,t2,1); if(!result) result = testForCompare(t1,t1->arr[t1i].lchild,t2); if(!result) result = testForCompare(t1,t1->arr[t1i].rchild,t2); } return result; }; int compare(TreeArr *t1,int t1i,TreeArr *t2,int t2i){ if(t2i == 0) return 1; if(t1i == 0) return 0; if(t1->arr[t1i].num != t2->arr[t2i].num) return 0; return compare(t1,t1->arr[t1i].lchild,t2,t2->arr[t2i].lchild)&&compare(t1,t1->arr[t1i].rchild,t2,t2->arr[t2i].rchild); } /************************************************************** Problem: 1520 User: xhalo Language: C Result: Accepted Time:10 ms Memory:912 kb ****************************************************************/