当前位置: 代码迷 >> 综合 >> Poj1026 Cipher(置换)
  详细解决方案

Poj1026 Cipher(置换)

热度:76   发布时间:2024-01-28 07:48:32.0

题意:

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

  相关解决方案