这个题去年就看到了,但是用模拟的办法超时了。如果每次模拟都记录下字符串还会内存超限。后来得知是置换群。每个字符的出现都是有周期的,这样整个串的周期就是所有字符周期的最小公倍数数。如果求了串的周期,k取模之后再模拟,还是会超时。正确的办法是k对每个字符的周期取模,然后对字符操作。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define MAXN 5000000
//ios::sync_with_stdio(false);
using namespace std;
int num[205],n,r[205];
void Init()
{
for(int i=1; i<=n; ++i)
{
int now=num[i],ed=i,cir=1;
while(now!=ed)
{
cir++;
now=num[now];
}
r[i]=cir;
}
}
void Set_text(char *str)
{
int l=strlen(str+1);
for(int i=l+1; i<=n; ++i)
str[i]=' ';
str[n+1]=0;
}
void solve(char *str1,char *str2,int k)
{
for(int i=1; i<=n; ++i)
{
int ed=(k-1)%r[i]+1,now=i;
for(int j=0; j<ed; ++j)
now=num[now];
str2[now]=str1[i];
}
str2[n+1]=0;
}
int main()
{
while(scanf("%d",&n)&&n)
{
for(int i=1; i<=n; ++i)
scanf("%d",&num[i]);
Init();
char str1[205],str2[205];
int k;
while(scanf("%d",&k)&&k)
{
char c;
getchar();
gets(str1+1);
Set_text(str1+1);
solve(str1,str2,k);
printf("%s\n",str2+1);
}
printf("\n");
}
return 0;
}