poj1026Cipher(置换群)

链接

找循环节 然后所有子循环节的最小公倍数就是总的循环节 找结果的时候也按一个个置换来进行转换 不然也TLE

 1     #include <iostream>
 2     #include<cstdio>
 3     #include<string>
 4     #include<cstring>
 5     #include<algorithm>
 6     #include<stdlib.h>
 7     #include<map>
 8     using namespace std;
 9     #define LL long long
10     int p[210];
11     char s[210];
12     char ss[210],sq[210];
13     int vis[210];
14     int qu[210][210];
15     int po[210];
16     int num[210];
17     LL gcd(int a,int b)
18     {
19         return b==0?a:gcd(b,a%b);
20     }
21     int main()
22     {
23         int i,j,n;
24         LL k;
25         while(scanf("%d",&n)&&n)
26         {
27             memset(vis,0,sizeof(vis));
28             memset(num,0,sizeof(num));
29             for(i = 1; i <= n ; i++)
30             {
31                 scanf("%d",&p[i]);
32                 po[p[i]] = i;
33             }
34             LL sk = 1;int g=0;
35             for(i =1; i <= n ;i++)
36             {
37                 if(!vis[i])
38                 {
39                     vis[i] = 1;
40                     g++;
41                     int x = i,o=1;
42                     qu[g][o] = i;
43                     while(1)
44                     {
45                         x = p[x];
46                         if(!vis[x])
47                         {
48                             vis[x] = 1;
49                         }
50                         else
51                         break;
52                         o++;
53                         qu[g][o] = x;
54                     }
55                     num[g] = o;
56                     sk = sk/gcd(sk,o)*o;
57                 }
58             }
59             while(scanf("%lld%*c",&k)&&k)
60             {
61                 gets(s);
62                 int kk = strlen(s);
63                 for(i = kk ; i < n ; i++)
64                 s[i] = ' ';
65                 s[n] = '';
66                 strcpy(ss,s);
67                 strcpy(sq,s);
68                 k = k%sk;
69                 for(i =1  ; i <= g ; i++)
70                 {
71                     int kk = k%num[i];
72                     strcpy(ss,sq);
73                     while(kk)
74                     {
75                         for(j = 1 ; j <= num[i] ; j++)
76                         s[qu[i][j]-1] = ss[po[qu[i][j]]-1];
77                         strcpy(ss,s);
78                         kk--;
79                     }
80                 }
81                 puts(s);
82             }
83             puts("");
84         }
85         return 0;
86     }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3330226.html