2255:Tree Recovery
keyword
2分木 C++
概要
ノード数26以下の2分木がある。(root, left subtree, right subtree)、(left subtree, root, right subtree)の順にノードを出力した文字列がそれぞれ与えられるので、(left subtree, right subtree, root)の順にノードを出力する問題。
ノード数が小さいので、素直に各ノードに対して左の子と右の子を調べる。左の子はすぐに分かるが右の子はちょっと面倒。
int leftChild[30], rightChild[30]; char ans[30]; char preorder[30], inorder[30]; int pre[30], in[30]; int pos, n; void dfs(int root){ if(leftChild[root]<30) dfs(leftChild[root]); if(rightChild[root]<30) dfs(rightChild[root]); ans[pos++] = (char)(root + 'A'); return ; } void dfs2(int root, int begin, int end){ int left = leftChild[root], right; if(left < 30){ dfs2(left, begin, in[root]); } if(in[root]<end-1){ if(left==30){ right = preorder[pre[root]+1]; } else{ for(right=preorder[pre[root]+1]; (in[right]<in[root] || in[right]>=end); right = preorder[pre[right]+1]); } rightChild[root] = right; dfs2(right, in[root]+1, end); } return ; } int main(){ int i, j; while(scanf("%s %s\n", preorder, inorder)!=EOF){ REP(i,26) leftChild[i] = rightChild[i] = pre[i] = in[i] = 30; n = strlen(preorder); REP(i,n)preorder[i] -= 'A'; REP(i,n)inorder[i] -= 'A'; REP(i,n) pre[preorder[i]] = i; REP(i,n) in[inorder[i]] = i; REP(i,26)if(pre[i]<30)REP(j,26)if(i!=j && pre[j]<30){ if(pre[i] + 1 == pre[j] && in[i] > in[j]) leftChild[i] = j; } dfs2(preorder[0], 0, n); pos = 0; dfs(preorder[0]); ans[pos] = '\0'; printf("%s\n",ans); } return 0; }