用n个不同的字符(编号1 - n),组成一个字符串,有如下2点要求:
- 1、对于编号为i 的字符,如果2 * i > n,则该字符可以作为最后一个字符,但如果该字符不是作为最后一个字符的话,则该字符后面可以接任意字符;
- 2、对于编号为i的字符,如果2 * i <= n,则该字符不可以作为最后一个字符,且该字符后面所紧接着的下一个字符的编号一定要 >= 2 * i。
问有多少长度为M且符合条件的字符串。
例如:N = 2,M = 3。则abb, bab, bbb是符合条件的字符串,剩下的均为不符合条件的字符串。
假定n和m皆满足:2<=n,m<=1000000000)。
#include <stdio.h>
#include <stdlib.h>
#define N 2
#define M 3
void findValidStr(char* elems, char* result, int pos) {
if (pos == M) {
result[M] = '\0';
puts(result);
} else {
if (pos == 0) {
int i = pos;
for (i = pos; i < N; i++) {
result[pos] = elems[i];
findValidStr(elems, result, pos + 1);
}
} else {
int i = 0;
//上一个元素编号
int lastI = result[pos - 1] + 1 - 'a';
//前半部分编号,后一元素升序
if (lastI * 2 <= N) {
i = lastI;
}
//最后一位必须在后半部分中取
if (pos == M - 1) {
if (i != lastI) {
i = N / 2;
}
}
for (; i < N; i++) {
result[pos] = elems[i];
findValidStr(elems, result, pos + 1);
}
}
}
}
int main(void) {
char elems[N] = { 'a', 'b' };
char result[M + 1];
int i = 0;
for (; i < N; i++) {
elems[i] = 'a' + i;
}
findValidStr(elems, result, 0);
return EXIT_SUCCESS;
}