因为全排列问题曾经仔细看过,有重集的全排列刘汝佳上也明确讲过,所以这次终于享受了一次 秒过水题的快感,以往都是被水题虐死T0T
这里比较小坑的是放在最后的一句话,注意了这个就没什么大问题了
Hint
An upper case letter goes before the corresponding lower case letter.
So the right order of letters is 'A'<'a'<'B'<'b'<...<'Z'<'z'.
So the right order of letters is 'A'<'a'<'B'<'b'<...<'Z'<'z'.
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
int n, len;
char str[20]; // 原始字符串
int num[20], arr[20], fre[55][2] = {0}; // 转换后数组,临时数组,频率数组
int cmp( const void* a, const void* b){
return *(int*)a - *(int*)b;
}
void dfs( int cur);
int main(void){
int i;
scanf("%d", &n);
getchar();
while( n--){
gets( str);
len = strlen( str);
for( i = 0; i < len; i++){ // 进行转换处理,到时候要转换回来
if( isupper(str[i])) num[i] = (str[i] - 'A')*2; // 转换规则是A=1 a=2 B=3...
else num[i] = (str[i] - 'a') * 2 + 1;
}
qsort( num, len, sizeof(int), cmp);
memset( fre, 0, sizeof(fre));
for( i = 0; i < len; i++){
fre[ num[i]][0]++; // fre[n][0]存储数字n的出现频率
}
dfs( 0);
}
return 0;
}
void dfs( int cur){
int i;
if( cur == len){
for( i = 0; i < len; i++){ // 输出,反加工
if( arr[i]%2 ) printf("%c", 'a' + arr[i]/2);
else printf("%c", 'A' + arr[i]/2);
}
printf("\n");
return;
}
for( i = 0; i < len; i++){
if( i && num[i] == num[i-1]) continue; // 查重,若连续都相同则跳过
if( fre[num[i]][0] > fre[num[i]][1]){ // fre[n][1]存储数字n的使用频率
arr[cur] = num[i];
fre[num[i]][1]++;
dfs( cur+1);
fre[num[i]][1]--; // 不能忘记取消使用
}
}
}