困難的串(Krypton Factor, UVa 129)回溯
阿新 • • 發佈:2019-01-10
如果一個字串包含兩個相鄰的重複子串,則稱它是“容易的串”,其他串稱為“困難的串”。例如,BB、ABCDACABCAB、ABCDABCD都是容易的串,而D、DC、ABDAB、CBABCBA都是困難的串。輸入正整數n和L,輸出由前L個字元組成的、字典序第k小的困難的串。例如,當L=3時,前7個困難的串分別為A、AB、ABA、ABAC、ABACA、ABACAB、ABACABA。輸入
保證答案不超過80個字元。
樣例輸入:
7 3
30 3
0 0
樣例輸出:
ABAC ABA
7
ABAC ABCA CBAB CABA CABC ACBA CABA
28
回溯遞迴,每次只需要考慮當前情況。每次只需要用新產生的字串和前面的字串對比即可(因為之前的已經比較過了),減少了對比量。
#include <iostream> #include <string> using namespace std; int n,m,cnt; string s; bool dfs(int cur){ if(cnt++==n){//cnt記錄第幾次 ,一直遞迴n次結束 for(int i=0;i<cur;i++){ if(i && i%(16*4)==0) cout<<endl; else if(i && i%4==0)cout<<" "; cout<<s[i]; } cout<<endl<<cur<<endl; return true; } for(int i=0;i<m;i++){ bool ok=true; s[cur]=char('A'+i); for(int j=1;2*j<=cur+1;j++){//每次比較j長的字串。 bool equal=true; for(int k=0;k<j;k++) if(s[cur-k]!=s[cur-k-j]){ equal=false; break;} if(equal){ ok=false; break; } } if(ok && dfs(cur+1)) return true;//如果找到解直接退出。 } return false; } int main(int argc, char** argv) { while(cin>>n>>m && (n || m)){ cnt=0; s.resize(n); dfs(0); } return 0; }