A1149. FBI樹--我的雙螺旋解法
阿新 • • 發佈:2018-11-17
問題描述 http://www.tsinsen.com/A1149
我們可以把由“0”和“1”組成的字串分為三類:全“0”串稱為B串,全“1”串稱為I串,既含“0”又含“1”的串則稱為F串。
FBI樹是一種二叉樹,它的結點型別也包括F結點,B結點和I結點三種。由一個長度為2N的“01”串S可以構造出一棵FBI樹T,遞迴的構造方法如下:
1)T的根結點為R,其型別與串S的型別相同;
2)若串S的長度大於1,將串S從中間分開,分為等長的左右子串S1和S2;由左子串S1構造R的左子樹T1,由右子串S2構造R的右子樹T2。
現在給定一個長度為2N的“01”串,請用上述構造方法構造出一棵FBI樹,並輸出它的後序遍歷序列。
輸入格式
第一行是一個整數N(0 <= N <= 10),第二行是一個長度為2N的“01”串。
輸出格式
包括一行,這一行只包含一個字串,即FBI樹的後序遍歷序列。
樣例輸入
3
10001011
樣例輸出
IBFBBBFIBFIIIFF
我的解法:可以把給定的看做葉節點,之後以此計算他們的父親節點。考慮到最後需要後序遍歷序列,所以逐層計算,藉助雙螺旋,節省空間,迴圈次數正比樹高。
#include<iostream> #include<string> #include<stdio.h> using namespace std; #define N 1<<11 char F[2][N]; int main() { int n; cin>>n; int i=0; int nn=2<<n; string s;getline(cin,s); getline(cin,s); while(i<nn) { if(s[i]=='1') F[0][i]='I'; else F[0][i]='B'; i++; } int t=1,bienum=1; int k=0,kk; int _n=nn>>1; int _length=_n; while(_n>1) { kk=(k+1)%2; for(int i=0,j=0;i<_length;i++) { F[kk][j++]=F[k][i]; if((i+1)%(2*t)==0&&i-t>-1) F[kk][j++]=(F[k][i]==F[k][i-t]?F[k][i]:'F'); } t=2*t+1; _n=_n/2; _length+=_n; k=kk; } for(int i=0,j=0;i<_length;i++) cout<<F[k][i]; cout<<endl; }