基本思路是递归枚举,对每一个位置每一次从'A'开始到'A'+L-1枚举,如果在这个位置的选择这个字母能使字符串成为‘Hard’,则计数,一直计数到N就立即输出答案。
判断是否是‘Hard’的方法,从末尾开始枚举长度为1的字符串一直到长度floor(Length/2)的字符串和前一个相同长度的字符串比较是否重复。
对于答案的输出,题目格式要求比较特殊,个人思路如下:第0个位置的字符,直接输出,从1到长度-1个位置的字符,先输出,然后判断是否输出空格或换行。如果位置 i % 4 == 3 && i % 63 == 0,则为行尾,输出换行;如果位置 i % 4 == 3 && i % 63 != 0,则输出空格。对于最后一个字符后面可能刚好是要输出空格或换行的位置,为了避免格式错误,单独输出。
最后用单独一行输出字符串的长度。
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int MAXN_LEN = 80 + 5; char ans[MAXN_LEN]; int N, Chars; bool flag; void Print(int cur) { // cur is the last pos to be printed printf("%c", ans[0]); for(int i=1; i<=cur; ++i) { printf("%c", ans[i]); if(i % 4 == 3 && i % 63 && i!=cur) { printf(" "); } if(i % 63 == 0) { printf(" "); } } if(!cur || cur % 63 != 0) { printf(" "); } printf("%d ", cur+1); } bool IsHard(int cur) { for(int j, i=1; i*2<=cur+1; ++i) { int pos = cur - i; for(j = 0; j<i ; ++j) { if( ans[pos-j] != ans[cur-j] ) { break; } } if( i == j ) { return false; } } return true; } int type; void Dfs(int cur) { for(int i=0; i<Chars; ++i) { ans[cur] = i+'A'; if(!flag && IsHard(cur) ) { type ++; if( type == N ) { Print(cur); flag = true; return ; } Dfs(cur+1); } } } int main() { while(cin >> N >> Chars) { if(N == 0 && Chars == 0) { break; } flag = false; type = 0; Dfs(0); } return 0; }
刚好这道题之后试着用java写了一下,附上java代码:
import java.util.Scanner; /** * Created by emerald on 8/7/15. * Uva129 */ public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); char str[] = new char[80 + 5]; while (true) { int N = in.nextInt(), L = in.nextInt(); if(N == 0 && L == 0) { break; } counter = 0; dfs(str, 0, N, L); } } public static int counter = 0; public static void dfs(char str[], int cur, int N, int L) { for(int i=0; i<L && counter < N; i ++) { str[cur] = (char) (i + 'A'); if(isHard(str, cur+1)) { counter++; if (counter == N) { printAns(str, cur+1); return; } else if(counter > N) { // printAns(str, cur + 1); return; } dfs(str, cur + 1, N, L); } } } public static void printAns(char str[], int length) { System.out.print(str[0]); for(int i=1; i<length-1; ++i) { System.out.print(str[i]); if (i % 4 == 3 && i % 63 == 0) { System.out.print(' '); } else if (i % 4 == 3 && i % 63 != 0) { System.out.print(' '); } } System.out.println(str[length-1]); System.out.println(length); } public static boolean isHard(char str[], int length) { for(int j, i=1; i*2<=length; ++i) { int former = length - 1 - i; int latter = length - 1; for(j=0; j<i; j ++) { if(str[former - j] != str[latter - j]) { break; } } if(i == j) { return false; } } return true; } }