感受我超廢。算法
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的)spa
#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的非暴力算法,你們看看就好:code
#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-blog