2020 BIT冬训-二分三分快速幂矩阵 L - Decode the Strings HDU - 2371

时间:2021-02-19 13:18:41   收藏:0   阅读:0

Problem Description

Bruce Force has had an interesting idea how to encode strings. The following is the description of how the encoding is done:

Let x1,x2,...,xn be the sequence of characters of the string to be encoded.

1. Choose an integer m and n pairwise distinct numbers p1,p2,...,pn from the set {1, 2, ..., n} (a permutation of the numbers 1 to n).
2. Repeat the following step m times.
3. For 1 ≤ i ≤ n set yi to xpi, and then for 1 ≤ i ≤ n replace xi by yi.

For example, when we want to encode the string "hello", and we choose the value m = 3 and the permutation 2, 3, 1, 5, 4, the data would be encoded in 3 steps: "hello" -> "elhol" -> "lhelo" -> "helol".

Bruce gives you the encoded strings, and the numbers m and p1, ..., pn used to encode these strings. He claims that because he used huge numbers m for encoding, you will need a lot of time to decode the strings. Can you disprove this claim by quickly decoding the strings?

InputThe input contains several test cases. Each test case starts with a line containing two numbers n and m (1 ≤ n ≤ 80, 1 ≤ m ≤ 109). The following line consists of n pairwise different numbers p1,...,pn (1 ≤ pi ≤ n). The third line of each test case consists of exactly n characters, and represent the encoded string. The last test case is followed by a line containing two zeros.
OutputFor each test case, print one line with the decoded string.
Sample Input

5 3
2 3 1 5 4
helol
16 804289384
13 10 2 7 8 1 16 12 15 6 5 14 3 4 11 9
scssoet tcaede n
8 12
5 3 4 2 1 8 6 7
encoded?
0 0

Sample Output

hello
second test case
encoded?
这题是寻找循环节。(跟他所在的题单好像完全没关系啊)
循环节就是重复一定次数后达到一种循环的状态。由于字符串的转换关系是不变的。固必然会出现循环。(具体论证懒得算了。鸽巢定理(吧))
寻找字符串的循环节比较困难且复杂且耗时。由于每个字符串最多只有80个字符。故我们可以对字符串内每一个字符寻找其循环节即可。
AC代码如下:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,p[85],temp,pos[85][85],cnt;
char s[85],ans[85]; 
int main(){
    while(scanf("%d%d",&n,&m),n){
        for(int i=0;i<n;i++){
            scanf("%d",&p[i]);
            p[i]--;
        }
        getchar();
        gets(s);
        for(int i=0;i<n;i++){
            cnt=0;
            temp=p[i];
            pos[i][cnt++]=i;
            while(temp!=i){
                pos[i][cnt++]=temp;//记录i在第cnt次循环在 什么位置 
                temp=p[temp];
            }
            ans[pos[i][m%cnt]]=s[i];
        }
        ans[n]=\0;
        printf("%s\n",ans);
    }
}

 

 
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!