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 }