POJ 1026 Cipher(置换群)

题目链接

题意 :由n个数字组成的密钥,每个数字都不相同,都在1~n之间,有一份长度小于等于n的信息,要求将信息放到密钥下边,一一对应,信息不足n的时候补空格,然后将位置重新排列,将此过程重复k次,求最后的字符串序列,最后的空格不用输出。

思路 :如果按照最原始的求循环结的话会超时,因为k值范围很大。所以要用置换群,把每个的元素的循环求出来,直接对其取余即可。会3270的话,这个题理解起来挺容易的。

 1 //1126

 2 #include <stdio.h>

 3 #include <string.h>

 4 #include <iostream>

 5 

 6 using namespace std ;

 7 

 8 int a[210],ch[210] ;

 9 char sh[210] ,pri[210];

10 

11 void xh(int n)

12 {

13     for(int i = 1 ; i <= n ; i++)

14     {

15         int cnt = 1 ;

16         int pos = a[i] ;

17         while(pos != i)

18         {

19             pos = a[pos] ;

20             cnt ++ ;

21         }

22         ch[i] = cnt ;

23     }

24 }

25 int main()

26 {

27     int n,k ;

28     while(~scanf("%d",&n) && n)

29     {

30         memset(a,0,sizeof(a)) ;

31         for(int i = 1 ; i <= n ; i++)

32             scanf("%d",&a[i]) ;

33         //memset(sh,0,sizeof(sh)) ;

34         xh(n) ;

35         while(~scanf("%d",&k) && k)

36         {

37             getchar() ;

38             gets(sh+1) ;

39             for(int i = strlen(sh+1) + 1 ; i <= n ; i++ )

40                 sh[i] = ' ' ;

41                 sh[n+1] = '\0' ;

42             for(int i = 1 ; i <= n ; i++)

43             {

44                 int pos = i ;

45                 for(int j = 0 ; j < k % ch[i] ; j ++)

46                     pos = a[pos] ;

47                 pri[pos] = sh[i] ;

48             }

49             pri[n+1] = '\0' ;

50             for(int i = 1 ; i <= n ; i++)

51                 printf("%c",pri[i]) ;

52             puts("") ;

53         }

54         puts("") ;

55     }

56     return 0 ;

57 }
View Code

 

你可能感兴趣的:(poj)