首页 > 代码库 > poj1026--Cipher

poj1026--Cipher

题意:看着样例说吧     给你n个数字a[i](>0&&<=n),再给你交换次数k,之后是一串字符串;如果字符串长度小于n,后面补为空格;然后进行交换:之前字符串的位置i对应的 a[i]位置就是交换一次后的字符位置,问交换k次后的字符串;

           分析:单纯模拟会超时,这其中有个规律:对于一个字符,交换某些次之后,就会变回原来的(即会循环),只需找出它的循环周期T,交换k%T次就可;

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <stdlib.h>
#define N 10010
#define INF 10000000
#define eps 10E-9
#define mem(a)  memset(a,0,sizeof(a))
using namespace std;
int a[N];
int a_circle[N];
char str[N];
char stre[N];
char s[N];
int circle(int x)//找周期
{
    int result=1,k=a[x];
    while(1)
    {
        if(x==k)
            return result;
        k=a[k];
        result++;
    }
}
int main()
{
    int n,k,i,j;
    while(~scanf("%d",&n)&&n)
    {
        for(i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
            a[i]=a[i]-1;
        }
        while(~scanf("%d",&k)&&k)
        {
            getchar();
            gets(str);
            int len=strlen(str);
            if(len<n)
            {
                for(i=len; i<n; i++)
                    str[i]=‘ ‘;
                str[i]=‘\0‘;
            }
            for(i=0; i<n; i++)
            {
                a_circle[i]=circle(i);
            }
            char c;
            for(i=0; i<n; i++)
            {
                int temp=k%a_circle[i];
                int d=i;
                // cout<<k<<endl;
                while (temp--)//交换
                    d = a[d];
                stre[d]=str[i];
            }
            for(i=0; i<n; i++)
                printf("%c",stre[i]);
            printf("\n");
        }
        printf("\n");
    }
    return 0;
}

poj1026--Cipher