洒洒。。。。
我究竟有多水啊,,
这道题我又是搞了3个小时,,,,无奈
思路倒不难,就是代码长了点,另外一开始的思路也不对,,,
树的编码问题,,,其实我的代码是暴力出来的,,,一位一位的确定,,,好在时间跑的还可以【0.009s】
#include <cstdio>
#include <cstring>
char s[35], ans[35], z;
int sort[27], n, ls;
long long fact(int x)//求阶乘
{
long long ans = 1;
for(int i = 2; i <= x; i++) ans*=i;
return ans;
}
int num_q()//返回当前位置的答案,,,
{
for(int k = 0; k < 26; k++) if(sort[k])
{
sort[k]-=1;
long long u = 0, d = 1;
int num = 0;
for(int i = 0; i < 26; i++) if(sort[i])
{
num+=sort[i];
if(sort[i]>=2)
d*=fact(sort[i]);
}
u = fact(num);
int mm = u/d;
if(mm<n) n-=mm;
else return k;
sort[k]+=1;
}
return 0;
}
int solve()
{
z = 0;
int mid = 0;
memset(sort,0,sizeof(sort));
int len = strlen(s);
for(int i = 0; i < len; i++) sort[s[i]-'a']++;
for(int i = 0; i < 26; i++)
{
if(sort[i]&1) {z = i+'a'; mid++; sort[i]-=1; }
sort[i]/=2;
}
if(mid>1) return -1;//如果字符串不能构成回文串,
int num = 0;
long long maxn = 0, u = 0, d = 1;
for(int i = 0; i < 26; i++) if(sort[i])
{
num+=sort[i];
if(sort[i]>=2)
d*=fact(sort[i]);
}
u = fact(num);
maxn = u/d;
if(n>maxn) return -1;
ls = len/2;
for(int i = 0; i < ls; i++)//一位一位的确定
ans[i] = num_q()+'a';
return 1;
}
int main()
{
int cas, tt = 0;
scanf("%d",&cas);
while(tt++ < cas)
{
int t;
scanf("%s %d",s,&n);
t = solve();
printf("Case %d: ",tt);
if(t==-1) {printf("XXX\n"); continue; }
for(int i = 0; i < ls; i++) printf("%c",ans[i]);
if(z) printf("%c",z);
for(int i = ls-1; i >= 0; i--) printf("%c",ans[i]);
printf("\n");
}
return 0;
}