题意:
给定一个排列置换,若干次询问
每次询问给定一个整数k和一个字符串
输出字符串进行k次置换得到的新串
数据范围:n<=200
解法:
置换是排列,可以抽象为若干有向环,我们要做的就是将每个点在环上走k步。
预处理出置换中的所有环,然后每个环中的元素单独处理,步数k对环的大小取模,可以O(1)计算出终点。
code:
#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int maxm=205;
int mark[maxm];
char s[maxm];
char ans[maxm];
int a[maxm];
int n,k;
signed main(){
while(cin>>n&&n){
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)mark[i]=0;
vector<int>cir[maxm];
int cnt=0;
for(int i=1;i<=n;i++){//找环
if(!mark[i]){
cnt++;
int x=i;
while(!mark[x]){
mark[x]=1;
cir[cnt].push_back(x);
x=a[x];
}
}
}
while(cin>>k&&k){
getchar();
gets(s+1);
int len=strlen(s+1);
while(len<n){
s[++len]=' ';
}
for(int i=1;i<=cnt;i++){
int cc=cir[i].size();
for(int j=0;j<cc;j++){
int pos=(j+k)%cc;//计算j走k步到达的位置
ans[cir[i][pos]]=s[cir[i][j]];
}
}
for(int i=1;i<=n;i++){
cout<<ans[i];
}
cout<<endl;
}
puts("");
}
return 0;
}