纯模拟规律。。逐步确定每一位。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define ll long long ll used[17]; ll f[27],ans[38]; ll sum[20]; ll len; char str[21]; ll Jc() { ll s=1,i; ll x[28]; memset(x,0,sizeof(x)); for(i=1;i<=len;i++) if(ans[str[i]-'A']!=0&&!used[i]&&!x[str[i]-'A']) { s*=f[ans[str[i]-'A']]; x[str[i]-'A']=1; } return s; } int main() { ll k; while(scanf("%s%lld",str,&k)!=EOF) { ll i,j; if(k==0&&str[0]=='#') break; len=strlen(str); memset(used,0,sizeof(used)); sort(str,str+len); for(i=len;i>=1;i--) str[i]=str[i-1]; ll n=len; memset(ans,0,sizeof(ans)); for(i=1;i<=n;i++) { int v=str[i]-'A'; ans[v]+=1; } f[1]=1; for(i=2;i<n;i++) f[i]=i*f[i-1]; for(i=1;i<n;i++) { sum[0]=0; int u=0,q=0; for(j=1;j<=n;j++) { if(used[j]) continue; if(str[j]==str[q]&&u!=0) continue; else { u++; q=j; ans[str[j]-'A']-=1; sum[u]=f[n-i]/Jc()+sum[u-1]; ans[str[j]-'A']+=1; } if(sum[u]>=k) { printf("%c",str[j]); ans[str[j]-'A']-=1; used[j]=1; k-=sum[u-1]; break; } } } for(i=1;i<=n;i++) if(!used[i]) printf("%c",str[i]); printf("\n"); } return 0; }
时间: 2024-10-05 05:42:10