UVa 306 - Cipher

传送门

UVa 306 - Cipher

题意

先给一串数字,意思是每一轮变换的时候对应这个数字的字母变换的位置。

然后给n句字母,问经过k次变换后长什么样。

思路

对于每个位置,最多换200次就会回到原位,所以只要求出每个位置的周期再算出变换$k \% circle$时的位置即可。

不过求周期的时候想晕了好久。。。

代码

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#pragma comment(linker, "/STACK:102400000,102400000")
const int MAXN = 200 + 10;
 
int prcp[MAXN], refer[MAXN], len[MAXN], n;
char ans[MAXN], str[MAXN];
 
void GetCircle()
{
    int i, j;
    for (i = 1; i <= n; i++)
        scanf("%d", &prcp[i]);
    for (i = 1; i <= n; i++)
    {
        int t = i, cnt = 1;
        while (prcp[t] != i)
        {
            t = prcp[t];
            cnt++;
        }
        len[i] = cnt;
    }
}
 
int main()
{
    //freopen("input.txt", "r", stdin);
    int i, j, k;
    while (scanf("%d", &n), n)
    {
        GetCircle();
        while (scanf("%d", &k), k)
        {
            gets(str);
            for (i = strlen(str); i <= n; i++)
                str[i] = 32;
            for (i = 1; i <= n; i++)
                refer[i] = i;
            for (i = 1; i <= n; i++)
                for (j = 1; j <= k % len[i]; j++)
                    refer[i] = prcp[refer[i]];
            for (i = 1; i <= n; i++)
                ans[refer[i]] = str[i];
            for (i = 1; i <= n; i++)
                putchar(ans[i]);
            printf("\n");
        }
        puts("");
    }
    return 0;
}

Powered by Jekyll and Theme by solid