POJ 1026 Cipher
题意:
n,然后n个数,每个数代表下一次到达的下标,这样不断得交换下去(置换群思想)。
给出k和字符串,通过上面的置换得出最终的字符串。
分析:
先找出每个置换群的长度和数字。并且记录每个数下一个置换。
然后对于每个置换群,只需要置换k%len(len是当前置换群的长度)。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int MAX=210;
int a[MAX];
bool vis[MAX];
int rot[MAX];
char s[MAX],ans[MAX];
int main()
{
// freopen("in.txt","r",stdin);
int n,k;
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
int visit=n;//寻找循环节
memset(vis,false,sizeof(vis));
memset(rot,0,sizeof(rot));
while(visit)
{
int i=1;
while(vis[i]) i++;
int begin=i;
int len=0;
while(1)
{
len++;
vis[i]=true;
i=a[i];
if(i==begin) break;
}
i=begin;
while(1)
{
rot[i]=len;
i=a[i];
if(i==begin) break;
}
visit-=len;
}
while(scanf("%d",&k)!=EOF&&k)
{
getchar();
gets(s+1);
for(int i=strlen(s+1)+1; i<=n; i++)
s[i]=' ';
s[n+1]='\0';
for(int i=1; i<=n; i++)
{
int num=k%rot[i];
int op=i;
for(int j=1; j<=num; j++) op=a[op];
ans[op]=s[i];
}
ans[n+1]='\0';
printf("%s\n",ans+1);
}
printf("\n");
}
return 0;
}
本文详细解析了POJ1026 Cipher问题,通过找出每个置换群的长度和数字,利用循环节的概念进行字符串的最终变换。从输入的数字序列出发,逐步置换并输出最终的字符串结果。

519

被折叠的 条评论
为什么被折叠?



