标签:ons 回溯 i++ clu 图片 cab code ring return
Problem UVA129-Krypton Factor
通过了光明狮子的考验,小渡来到了创界山的第二层。没想到第二层的守护神——火焰凤凰正沉迷于字母游戏,不能自拔!为了尽快得到她的帮助,小渡决定出手帮她解决字母游戏的谜题。 字母游戏规则是这样的:
一个字母串里包含有两个相邻的重复子串则称为“水串”,否则为“火串”
例如AA、ABCABC都是"水串",而D、DC、ABDAD、CBABCBA都是“火串"。
输入正整数L和n,输出由前L个字母组成的、字典序第n个的"火串"。
多组输入n和L,1<=L<=26,n>0。输入0 0结束。
对于每个输入,输出第n个"火串"。在下一行输出“火串”的长度。你可以假设对于给定的L和n,至少存在n个“火串”。
由于这样的序列可能非常长,每4个字母分割成一组, 如果有超过16个这样的小组,请为第17组开始新的一行。
假设最大“火串”长度为80。
例如,当L = 3时,前7个“火串”是:
A
AB
ABA
ABAC
ABACA
ABACAB
ABACABA
ABAC ABA
7
ABAC ABCA CBAB CABA CABC ACBA CABA
28
题解:回溯法。当判断下一个字母能否添加进来时,只需判断目前字符串的后缀即可。
P.S.这个题的输出确实比较坑
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 using namespace std; 6 7 const int maxl = 100; 8 int n,L,cnt; 9 char ans[maxl]; 10 bool ok; 11 12 bool Can_Prune(char *str){ 13 int cur = strlen(str); 14 for(int i = (cur+1)>>1;i < cur;i++){ 15 int len = cur-i; 16 int st = i-len; 17 char tmp[maxl]; 18 strncpy(tmp,str+st,len*sizeof(char)); 19 tmp[len] = 0; 20 if(!strcmp(tmp,str+i)) return true; 21 } 22 return false; 23 } 24 25 void dfs(char *ss,int cur){ 26 if(ok) return; 27 for(int i = 0;i < L;i++){ 28 char ch = i+‘A‘; 29 ss[cur] = ch; 30 ss[cur+1] = ‘\0‘; 31 if(cur>0 && Can_Prune(ss)) continue; 32 cnt++; 33 if(cnt == n){ 34 ok = true; 35 int con = 0,len = strlen(ss); 36 for(int i = 0;i < len;i++){ 37 printf("%c",ss[i]); 38 if(i%4==3 && i!=len-1){ 39 con++; 40 if(con == 16){ 41 con = 0; 42 printf("\n"); 43 } 44 else printf(" "); 45 } 46 } 47 printf("\n"); 48 printf("%d\n",len); 49 return; 50 } 51 dfs(ss,cur+1); 52 } 53 } 54 55 int main() 56 { 57 //freopen("input.txt","r",stdin); 58 //freopen("output.txt","w",stdout); 59 while(~scanf("%d%d",&n,&L) && (n||L)){ 60 cnt = 0; 61 ok = false; 62 memset(ans,0,sizeof(ans)); 63 dfs(ans,0); 64 } 65 return 0; 66 }
标签:ons 回溯 i++ clu 图片 cab code ring return
原文地址:https://www.cnblogs.com/npugen/p/9536052.html