【6.10校内test】T1 FBI树
感觉我超废。
MY SOLUTION:
我的想法其实也是很简单的,递归的去做,因为最后要求输出FBI的后序遍历,也就是左右头,我的方法是递归存字符数组,(按照与后序遍历完全相反的顺序存的),然后倒序输出。非常遗憾的是,因为开始时写递归写炸了(微笑),于是我修改递归变成了main函数里先进行判整个串,当n=0时,就输出了两位。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n, cnt; char a[2000]; char c[2000]; int pd(int x, int y) {//写了一个复杂的判断函数 if (x == y) { if (a[x] == '1') return 1; else return 0; } for (int i = x + 1; i <= y; i++) if (a[i] != a[i - 1]) return 2; if (a[x] == '1') return 1; if (a[x] == '0') return 0; } int solve(int f, int len) { int d = (len + f) >> 1; int num = len; if (f > len) return 0; if (pd(f, len) == 2) c[++cnt] = 'F'; if (pd(f, len) == 1) c[++cnt] = 'I'; if (pd(f, len) == 0) c[++cnt] = 'B'; if (f == len) return 0; len >>= 1; solve(d + 1, num); solve(f, d); return 0; } int main() { scanf("%d", &n); scanf("%s", a + 1);//输入 from a[1]; int len = strlen(a + 1);//求a[1] to a[len] 的长度; if (pd(1, len) == 2) c[1] = 'F'; if (pd(1, len) == 1) c[1] = 'I'; if (pd(1, len) == 0) c[1] = 'B'; cnt++; int g = len >> 1; solve(g + 1, len);//因为后序遍历,故先递归右子树 solve(1, g); if (n == 0) {//被坑的地方,因为n==0时,如果按我的递归方式cnt=2; cout << c[1] << endl; return 0; } for (int i = cnt; i >= 1; i--) cout << c[i]; return 0; }
我想改一改我的这个代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n, cnt; char a[2000]; char c[2000]; int pd(int x, int y) { for (int i = x + 1; i <= y; i++) if (a[i] != a[i - 1]) return 2; if (a[x] == '1') return 1; if (a[x] == '0') return 0; } int solve(int f, int len) { if(f==len) {if(a[f]=='1') c[++cnt]='I'; else c[++cnt]='B'; return 0;} int d = (len + f) >> 1; if(f>len) return 0; if (pd(f, len) == 2) c[++cnt] = 'F'; if (pd(f, len) == 1) c[++cnt] = 'I'; if (pd(f, len) == 0) c[++cnt] = 'B'; solve(d+1,len); solve(f,d); return 0; } int main() { scanf("%d", &n); scanf("%s", a + 1); int len = strlen(a + 1); solve(1, len); for (int i = cnt; i >= 1; i--) cout << c[i]; return 0; }
WATER_LIFT'S SOLUTION:(是我手打的但思路是water_lift的)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n, cnt; char a[2000]; char c[2000]; int pd(int x, int y) { if (x == y) { if (a[x] == '1') return 1; else return 0; } for (int i = x + 1; i <= y; i++) if (a[i] != a[i - 1]) return 2; if (a[x] == '1') return 1; if (a[x] == '0') return 0; } int solve(int f, int len) { if(f==len) { if(a[f]=='1') cout<<"I"; if(a[f]=='0') cout<<"B"; return 0; } int d = (len + f) >> 1; solve(f,d); solve(d+1,len); if (pd(f, len) == 2) cout<<"F"; if (pd(f, len) == 1) cout<<"I"; if (pd(f, len) == 0) cout<<"B"; return 0; } int main() { scanf("%d", &n); scanf("%s", a + 1); int len = strlen(a + 1); solve(1,len); return 0; }
至于water_lift的非暴力算法,大家看看就好:
#include <iostream> #include <string> using namespace std; int n; string s; char dfs(int l, int r) { if (l == r) { if (s[l] == '0') { cout << 'B'; return 'B'; } else if (s[l] == '1') { cout << 'I'; return 'I'; } } int mid = (l + r) / 2; char le = dfs(l, mid); char ri = dfs(mid + 1, r); if (le == 'B' && ri == 'B') { cout << 'B'; return 'B'; } if (le == 'I' && ri == 'I') { cout << 'I'; return 'I'; } cout << 'F'; return 'F'; } int main() { freopen("fbi.in", "r", stdin); freopen("fbi.out", "w", stdout); cin >> n >> s; dfs(0, (1 << n) - 1); cout << endl; }
end-