标签:
问题链接:UVA129 Krypton Factor。问题简述:题目是氪因子。输入正整数n和L,输出由前L个字符组成的、字典顺序第n小的不含相邻重复字串的字符串。不含相邻重复字串的字符串是指,一个字符串中,任意两个相邻的字串都不相等。输出结果时,对于找到的字符串,每4个字符间加入一个空格,每行输出80个字符。
问题分析:回溯法实现。从第1个字符开始试探,每个字符从"A"开始可以是L个字符之一,直到遇见第n个满足条件的字符串。试探过程中,当前的串是不包含相邻相同子串的,所以只需要考虑加入一个字符之后,是否变为包含相邻相同子串。程序说明:函数check()用于检查一个串是否有相邻的相等的子串,如果没有则返回true,否则返回false。
AC的C++语言程序如下:
/* UVA129 Krypton Factor */ #include <iostream> using namespace std; const int MAXN = 80; int n, l, count; char v[MAXN+1]; // 判定是否有相邻的重复子串:只需要考虑追加1个字符后是否产生相邻重复子串 bool check(int curr) { for(int i=1; i<=(curr + 1) / 2; i++) { bool equal = true; for(int j=0; j<i; j++) if(v[curr - i - j] != v[curr - j]) { equal = false; break; } if(equal) return false; } return true; } void output_result(int curr) { for(int i=0; i<=curr; i++) { if(i % 4 == 0 && i > 0) { if(i % 64 == 0 && i > 0) putchar('\n'); else putchar(' '); } putchar(v[i]); } printf("\n%d\n", curr+1); } // 对于第curr字符,从‘A’到第l个字母都试探一遍 int dfs(int curr) { for(int i=0; i<l; i++) { v[curr] = 'A' + i; if(check(curr)) { if(++count == n) { v[curr + 1] = '\0'; output_result(curr); return 1; } else if(dfs(curr + 1)) return 1; } } return 0; } int main() { while(cin >> n >> l) { if(n == 0 && l == 0) break; count = 0; dfs(0); } return 0; }
标签:
原文地址:http://blog.csdn.net/tigerisland45/article/details/52245854