poj1026 Cipher(置换)

题目链接
题目翻译

分析:
理解题意之后,我们计算出轮换的大小
每一位每一位的模拟
i i 位的交换次数=m(mod)sizei
这点零头,我们直接模拟即可

#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

const int N=205;
int n,m,a[N],len,c[N],belong[N],cnt;
char s[N],ans[N];
bool p[N];

int init()
{
    memset(s,0,sizeof(s));
    char c;
    c=getchar(); c=getchar(); 
    len=0;
    while (c!='\n')
    {   
        s[++len]=c;
        c=getchar();
    }
    for (int i=len+1;i<=n;i++) s[i]=' ';
    return 0;
}

int main()
{
    while (scanf("%d",&n)!=EOF)
    {
        memset(p,0,sizeof(p)); cnt=0;
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        for (int i=1;i<=n;i++) if (!p[i])            //计算轮换 
        {
            cnt++;
            int x=i,l=0;
            do{
                l++; p[x]=1; belong[x]=cnt; x=a[x]; 
            }
            while (x!=i);
            c[cnt]=l;
        }

        while (scanf("%d",&m)!=EOF&&m)
        {
            init();
            for (int i=1;i<=n;i++)
            {
                int l=(m%c[belong[i]]);
                int x=i;
                for (int j=1;j<=l;j++) x=a[x];
                ans[x]=s[i];
            }
            for (int i=1;i<=n;i++) printf("%c",ans[i]);
            printf("\n");
        }

        printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值