http://poj.org/problem?id=1026
题意:有个字符串,按照给定的指环规则进行置换,也就是num[i]和第i个进行指环,求置换后的字符串
思路:找出循环节,所谓的循环结就是,这N个数字进行循环,那么循环N次后,这N个数字肯定还是和第一次是一样的。
比如说
1 2 3 4 5 6 7 8 9 10
4 5 3 7 2 8 1 6 10 9
那么循环结分别为(1,4,7),(2,5),(3),(6,8),(9,10)。
因为他们交换之后的顺序,只有可能在这循环节中的某个位置
参考 http://www.myexception.cn/program/1724584.html
1 #include <stdio.h> 2 #include <string.h> 3 4 5 6 int num[ 205 ]; 7 char str[ 205 ]; 8 int n,m,k,cnt; 9 int node[ 205 ][ 205 ]; 10 bool vis[ 205 ]; 11 12 void getnode() 13 { 14 cnt = 0; 15 int tmp; 16 memset(vis,true,sizeof(vis)); 17 for(int i = 1;i<=n;i++) 18 { 19 int len = 0; 20 tmp = i; 21 while(vis[tmp]) 22 { 23 node[cnt][++len] = tmp; 24 vis[tmp] =false; 25 tmp = num[tmp]; 26 } 27 if(len) 28 node[cnt++][0] = len; 29 } 30 } 31 32 void solve() 33 { 34 for(int i = 0;i<cnt;i++) 35 { 36 int len = m%node[i][0]; 37 while(len--) 38 { 39 for(int j = 2;j <= node[i][0];j++) 40 { 41 char tmp = str[node[i][j]]; 42 str[node[i][j]] = str[node[i][1]]; 43 str[node[i][1]] = tmp; 44 } 45 } 46 } 47 printf("%s\n",str+1); 48 } 49 50 51 int main() 52 { 53 while(scanf("%d",&n),n) 54 { 55 for(int i =1;i<=n;i++) 56 scanf("%d",&num[i]); 57 getnode(); 58 while(scanf("%d",&m),m) 59 { 60 gets(str); 61 for(int i = strlen(str);i<=n;i++) 62 str[i]=' '; 63 str[n+1] = '\0';4 5 3 7 2 8 1 6 10 9 64 solve(); 65 } 66 printf("\n"); 67 } 68 return 0; 69 }