POJ1026 Cipher

题目来源:http://poj.org/problem?id=1026

题目大意:

  Bob和Alice使用了一种全新的编码方式进行通信。密钥是一组整数序列:a1,a2,...,an,每个数都大于0,小于等于n.编码方式为:第i个字符换至ai位置处。然后得到的编码再编码一次,如此重复k次。信息的长度小于等于n,如果程度小于n,则后面用空格补齐。写一个程序读入编码规则和待编码字符串,输出编码结果。

输入:若干块数据组成,每块一个测试用例,第一行为串长n(1<=n<=200),第二行为密钥序列a1,a2,...an。第三行的第一个数为编码重复次数k,然后是待编码字符串。以0为该用例的结束。最后用一个0表示所有输入的结束。

输出:对每个待编码的字符串,输出编码后的字符串。每块对于的输出结束后加一个空白行。


Sample Input

10
4 5 3 7 2 8 1 6 10 9
1 Hello Bob
1995 CERC
0
0

Sample Output

BolHeol  b
C RCE

当k很大时直接模拟会TLE,字符串的长度n最长为200,最多重复n次后编码会回到编码前的状态,即一定存在一个“周期”,其值小于等于n。所以最多只需要计算200次,用求模运算可以得到所需的k次编码后的结果。

 1 //////////////////////////////////////////////////////////////////////////
 2 //        POJ1026 Cipher
 3 //        Memory: 408K        Time: 110MS
 4 //        Language: C++        Result: Accepted
 5 //////////////////////////////////////////////////////////////////////////
 6 
 7 #include <iostream>
 8 #include <stdio.h>
 9 #include <string>
10 
11 using namespace std;
12 
13 int key[201];
14 int queue[201][201];
15 int p[201];
16 int n;
17 char m[201];
18 char em[201];
19 int k;
20 
21 int main() {
22     while (true) {
23         cin >> n;
24         if (n == 0) break;
25         memset(m, 0, sizeof(m));
26         memset(em, 0, sizeof(em));
27         for (int i = 0; i < n; ++i) {
28             int t;
29             cin >> t;
30             key[i] = t - 1;
31         }
32         for (int i = 0; i < n; ++i) {
33             p[i] = 1;
34             queue[i][0] = i;
35         }
36         for (int i = 0; i < n; ++i) {
37             int k = 1;
38             while (true) {
39                 queue[i][k] = key[queue[i][k - 1]];
40                 if (queue[i][k] == i) {
41                     break;
42                 } else {
43                     ++k;
44                     ++p[i];
45                 }
46             }
47         }
48         while (true) {
49             scanf("%d", &k);
50             if (k == 0) break;
51 
52             getchar();
53             cin.getline(m, sizeof(m));
54             int len = strlen(m);
55             for (int i = len; i < n; ++i) {
56                 m[i] = ' ';
57             }
58             for (int i = 0; i < n; ++i) {
59                 int t = k % p[i];
60                 em[queue[i][t]] = m[i];
61             }
62             printf("%s\n", em);
63         }
64         printf ("\n");
65     }
66     system("pause");
67     return 0;
68 }
View Code
posted @ 2013-07-31 21:55  小菜刷题史  阅读(680)  评论(0编辑  收藏  举报