题目大意:

给定了一组对应关系,经过k次幂后,得到新的对应关系b[i],然后将给定的字符串上的第i位字符放置到b[i]的位置上,

如果字符串长度不足n就用空格补足,这里的是空格,也就是str[i] = ' ',不是str[i]='\0' ,自己这里错了好几回就是找不到问题,看了别人代码才明白

 

置换群的k次幂问题不清楚,可以看看<<置换群快速幂运算+研究与探讨.pdf>>

这里初始给定的置换群要注意这个群不一定是一个循环集,我们要先统计出它的每一个循环集,然后每一个分别进行操作计算

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 const int N = 205;
 6 //qun[i]保存第i个循环集的第一个数,a[]表示原映射,b[]表示k次幂后得到的新的对应关系,cnt表示循环集的个数
 7 int a[N] , b[N] , tmp[N] , tmp_new[N] , qun[N] , vis[N] , cnt;
 8 char str[N];
 9 
10 void circle(int u)
11 {
12     qun[cnt] = u;
13     int v = u;
14     while(u != a[v]){
15         vis[v] = 1;
16         v = a[v];
17     }
18     vis[v] = 1;
19     cnt++;
20 }
21 //返回当前循环集的长度
22 int get_tmp(int cnt)
23 {
24     int index = 0;
25     tmp[index++] = qun[cnt];
26    // cout<<"here: "<<cnt<<" start: "<<qun[cnt]<<endl;
27     int u = a[qun[cnt]];
28     while(u != tmp[0]){
29         tmp[index++] = u;
30         u = a[u];
31     }
32     return index;
33 }
34 
35 int main()
36 {
37    // freopen("a.in" , "r" , stdin);
38     int n , k;
39     while(scanf("%d" , &n) , n)
40     {
41         for(int i=1 ; i<=n ; i++)
42             scanf("%d" , a+i);
43 
44         memset(vis , 0 ,sizeof(vis));
45         cnt = 0;
46         //初始置换群中可能有多个循环集,我们需要一个一个循环集进行操作
47         for(int i=1 ; i<=n ; i++)
48             if(!vis[i]) circle(i);
49 
50         while(scanf("%d" , &k) , k){
51             getchar();
52             gets(str+1);
53             int len = strlen(str+1);
54             for(int i=len+1 ; i<=n ; i++)
55                 str[i] = ' ';
56            // printf("%s\n" , str+1);
57             for(int i=0 ; i<cnt ; i++){
58                 int len = get_tmp(i);
59 
60                 int index = 0 , pos = 0;
61                 tmp_new[index++] = tmp[0];
62 
63                 memset(vis , 0 , sizeof(vis));
64                 vis[0] = 1;
65                 for(int i=1 ; i<len ; i++){
66                     pos = (pos+k)%len;
67                     //分裂成了一个小循环集
68                     if(vis[pos]){
69                         for(int i=0; i<index ; i++){
70                             if(i <index-1) b[tmp_new[i]] = tmp_new[i+1];
71                             else b[tmp_new[i]] = tmp_new[0];
72                         }
73                         //tmp数组下标清零
74                         index = 0;
75                         pos = (pos+1)%len;
76                     }
77                     tmp_new[index++] = tmp[pos];
78                     vis[pos] = 1;
79                 }
80                 //最后一个分裂出来的循环集的映射加入到b中
81                 for(int i=0; i<index ; i++){
82                     if(i <index-1) b[tmp_new[i]] = tmp_new[i+1];
83                     else b[tmp_new[i]] = tmp_new[0];
84                 }
85             }
86 
87             char ans[N];
88             for(int i=1 ; i<=n ; i++){
89                 ans[b[i]] = str[i];
90             }
91             ans[n+1] = '\0';
92             printf("%s\n" , ans+1);
93         }
94         puts("");
95     }
96     return 0;
97 }

 

 posted on 2015-01-22 21:43  Love风吟  阅读(365)  评论(0编辑  收藏  举报