题目大意:
给定了一组对应关系,经过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 }
我还在坚持,我还未达到我所想,梦~~一直在