Description
Solution
这是我唯一会做的题,结果还没A,真是可惜
首先可以大胆猜想答案就是cl+l−1cl+l−1,即相邻的两个排列共用l-1个字符
考虑把所有排列搞出来,对于前l-1个和后l-1个相同的排列连边,这样我们需要找到一条哈密顿路径,显然这是不可做的
考虑把长度为l-1的排列搞出来,把相邻关系变成边上的关系,那么我们就需要找到一条欧拉回路,显然这是可以用圈套圈做的
这里其实没有必要求出所有的排列,只需要用字符集进制数表示一个串即可
Code
#include <stdio.h>
#include <math.h>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)
typedef long long LL;
const int N=10485770;
short d[N],rec[N];
int prt[N],stack[N],top,c,l,n=1;
char str[50];
void solve() {
int now,tar;
for (stack[++top]=0;1;) {
now=stack[top];
if (d[now]<c) {
tar=now%n*c+d[now];
rec[top]=d[now];
d[now]++;
stack[++top]=tar;
} else {
if (top>1) {
prt[++prt[0]]=rec[top--];
} else break;
}
}
}
int main(void) {
freopen("life.in","r",stdin);
freopen("life1.out","w",stdout);
scanf("%d%d",&c,&l);
scanf("%s",str);
LL ans=1; rep(i,1,l) ans=ans*c;
ans=ans+l-1;
printf("%lld\n", ans);
if (l==1) {
rep(i,0,c-1) putchar(str[i]);
return 0;
}
rep(i,3,l) n=n*c;
solve();
rep(i,1,l-1) putchar(str[0]);
drp(i,prt[0],1) putchar(str[prt[i]]);
return 0;
}