蛋疼了好长时间,还是早上精神好,理解的快一些。
就是求一个序列置换k次后的结果,由于肯定是循环的,我一开始做的是求出每个循环的长度,再求出最小公倍数m,
用k%m,即置换k%m次即为最后的答案,但是无情的TLE了。
后来才想懂,其实每个元素都属于一个小的循环,假设长度为len[i],只需要让这个元素在它所在的小循环里循环k%len[i]次即可
//============================================================================
// Name : 1026.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
using namespace std;
int n, k;
int m;
int a[220], b[220], len[220];
char s[220], c, ans[220];
void Circle(){
memset(len, 0, sizeof(len));
int temp, t, curlen;
for(int i = 1;i <= n;i++){
temp = i;
t = a[i];
curlen = 1;
while(t != temp){
curlen++;
t = a[t];
}
len[i] = curlen;
}
}
int main() {
freopen("a.txt", "r", stdin);
while(scanf("%d", &n)&&n){
for(int i = 1;i <= n;i++){
scanf("%d", &a[i]);
}
Circle();
while(scanf("%d", &k)&&k){
scanf("%c", &c);
for(int i = 1;i <= n;i++){
s[i] = ' ';
}
for(int i = 1;i <= n;i++){
scanf("%c", &c);
if(c == '\n'){
break;
}
s[i] = c;
}
for(int i = 1;i <= n;i++){
b[i] = i;
}
for(int i = 1;i <= n;i++){
for(int j = 1;j <= k%len[i];j++){
b[i] = a[b[i]];
}
}
// for(int i = 1; i <= n;i++){
// printf("%d ", b[i]);
// }
// printf("\n");
for(int i = 1;i <= n;i++){
ans[b[i]] = s[i];
}
for(int i = 1;i <= n;i++){
printf("%c", ans[i]);
}
printf("\n");
}
printf("\n");
}
return 0;
}