题意:有一种加密的方法,先给出 n 个数字的排列, 然后输入一个字符串,字符串长度 <= n。 当字符串长度小于n的时候,在其后面加上空格字符,使其长度等于n。
例如 4 5 3 7 2 8 1 6 10 9, Hello Bob, 然后从左到右让字符串的每一个字符与一个数字对应:
4 5 3 7 2 8 1 6 10 9
H e l l o B o b ‘ ’ ‘ ‘
假如加密后的到的新字符串用encode[]表示,那么加密过程就是encod[4] = H, encod[5] = e, encod[3] = l····。
连续加密K次,每一次在前一次得到的信息之上再加密。
题解:一开始直接模拟,然后判断整个字符串的循环节。TLE。然后想是不是可以先求出循环的K次幂,···没有下文。最后想到求单个字符的循环节,AC。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 300
int p[MAXN], loop[MAXN];
char mess[MAXN], encode[MAXN];
int n, k;
void permute ()
{
int now, i;
memset(loop,0,sizeof(loop));
for ( i = 0; i < n; i++ )
{
now = p[i];
loop[i] = 1;
while ( now != i )
{
loop[i]++;
now = p[now];
}
}
for ( i = 0; i < n; i++ )
{
int t = k % loop[i];
now = i;
while ( t-- ) now = p[now];
encode[i] = mess[now];
}
}
void print()
{
for ( int i = 0; i < n; i++ )
printf("%c",encode[i]);
printf("\n");
}
int main()
{
while ( scanf("%d",&n) && n )
{
int num, i;
for ( i = 0; i < n; i++ )
{
scanf("%d",&num);
p[num-1] = i;
}
while ( scanf("%d",&k) && k )
{
getchar(); gets(mess);
for ( i = strlen(mess); i < n; i++ ) mess[i] = ' ';
mess[n] = '\0';
permute();
print();
}
printf("\n");
}
return 0;
}