poj 1026

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 }

 

posted @ 2017-04-14 15:45  一个_小菜鸟  阅读(246)  评论(0编辑  收藏  举报