置换循环的应用。起初的状态为1,2,3......n,变换一次变为题目给出的序列,找出每个循环,可知每次变换每个字符的位置都是由本循环中的位置循环移动而来,通过模运算可得出每个字符在变换了多次之后,应该在的位置。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxn=200+10; 6 char s[maxn],re[maxn]; 7 int num[maxn],vis[maxn],cir[maxn][maxn],tot,st[maxn]; 8 void getC(int n) 9 { 10 int i,cou; 11 for(i=1;i<=n;i++) 12 { 13 if(!vis[i]) 14 { 15 cou=0; 16 tot++; 17 cir[tot][cou++]=i; 18 vis[i]=1; 19 int j=num[i]; 20 while(j!=i) 21 { 22 cir[tot][cou++]=j; 23 j=num[j]; 24 vis[j]=1; 25 } 26 st[tot]=cou; 27 } 28 } 29 } 30 int main() 31 { 32 int n; 33 while(scanf("%d",&n)&&n) 34 { 35 int i,j,k; 36 for(i=1;i<=n;i++) scanf("%d",&num[i]); 37 memset(vis,0,sizeof(vis)); 38 tot=0; 39 getC(n); 40 getchar(); 41 while(gets(s)&&strcmp(s,"0")!=0) 42 { 43 char* t=s; 44 int val=0; 45 while(*t!=' ') 46 val=val*10+(*(t++)-'0'); 47 t++; 48 i=strlen(t); 49 for(;i<n;i++) t[i]=' '; 50 t[i]='\0'; 51 int loc; 52 for(i=1;i<=tot;i++) 53 { 54 for(j=0;j<st[i];j++) 55 { 56 loc=(j+val)%st[i]; 57 re[cir[i][loc]-1]=t[cir[i][j]-1]; 58 } 59 } 60 re[n]='\0'; 61 printf("%s\n",re); 62 } 63 printf("\n"); 64 } 65 return 0; 66 }