题意:
给定一个置换,若干次询问
每次询问给定一个整数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;
}