ACM集训——POJ_1107

来源:互联网 发布:辩证看待人工智能 编辑:程序博客网 时间:2024/05/16 14:21

            第二道,还是英文题,生词比较多,理解题目用了好半天。

            上题,POJ_1107

            

W's Cipher
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 5110 Accepted: 2568

Description

Weird Wally's Wireless Widgets, Inc. manufactures an eclectic assortment of small, wireless, network capable devices, ranging from dog collars, to pencils, to fishing bobbers. All these devices have very small memories. Encryption algorithms like Rijndael, the candidate for the Advanced Encryption Standard (AES) are demonstrably secure but they don't fit in such a tiny memory. In order to provide some security for transmissions to and from the devices, WWWW uses the following algorithm, which you are to implement. 

Encrypting a message requires three integer keys, k1, k2, and k3. The letters [a-i] form one group, [j-r] a second group, and everything else ([s-z] and underscore) the third group. Within each group the letters are rotated left by ki positions in the message. Each group is rotated independently of the other two. Decrypting the message means doing a right rotation by ki positions within each group. 

Consider the message the_quick_brown_fox encrypted with ki values of 2, 3 and 1. The encrypted string is _icuo_bfnwhoq_kxert. The figure below shows the decrypting right rotations for one character in each of the three character groups. 

Looking at all the letters in the group [a-i] we see {i,c,b,f,h,e} appear at positions {2,3,7,8,11,17} within the encrypted message. After a right rotation of k1=2, these positions contain the letters {h,e,i,c,b,f}. The table below shows the intermediate strings that come from doing all the rotations in the first group, then all rotations in the second group, then all the rotations in the third group. Rotating letters in one group will not change any letters in any of the other groups. 

All input strings contain only lowercase letters and underscores(_). Each string will be at most 80 characters long. The ki are all positive integers in the range 1-100. 

Input

Input consists of information for one or more encrypted messages. Each problem begins with one line containing k1, k2, and k3 followed by a line containing the encrypted message. The end of the input is signalled by a line with all key values of 0.

Output

For each encrypted message, the output is a single line containing the decrypted string.

Sample Input

2 3 1_icuo_bfnwhoq_kxert1 1 1bcalmkyzx3 7 4wcb_mxfep_dorul_eov_qtkrhe_ozany_dgtoh_u_eji2 4 3cjvdksaltbmu0 0 0

Sample Output

the_quick_brown_foxabcklmxyzthe_quick_brown_fox_jumped_over_the_lazy_dogajsbktcludmv

Source

Mid-Central USA 2001

      这也是一道简单题,与加密解密有关,理解题意后,整理下思路,分三组,在输入的已加密文中,根据范围,分到相应组,再根据整数key,把分组的后key个调到改组前面,调整过程中,三组之间互不影响,最后得到解密文。就是一个字符串的分组轮换,技巧性一点的就可考虑——

用STL list实现字符串的轮换。

用STL map建立字母与位置之间的对应。


将26个字母分为 a-i  j-r  s-z三组。 下划线属于第三组。 给出每组 字符向右轮换 的次数。
组内全部轮换后输出交换后的结果。


#include <iostream>#include <stdio.h>#include <map>#include <list>using namespace std;int main() {int k[3];while (cin >> k[0] >> k[1] >> k[2]) {map<int, char> gp[3];
list<char> w[3];
                <span style="font-family: 'Times New Roman', Times, serif; ">//</span><span style="font-family: 'Times New Roman', Times, serif; ">用三组map存每组字符的初始位置。三组list存字符。</span>if (k[0] == 0 && k[1] == 0 && k[2] == 0)break;getchar();char ch;int n = 0;while ((ch = getchar()) != '\n') {if (ch >= 'a' && ch <= 'i') {gp[0][n];w[0].push_back(ch);}else if (ch >= 'j' && ch <= 'r') {gp[1][n];w[1].push_back(ch);}else {gp[2][n];w[2].push_back(ch);}n++;}
                //<span style="font-family: 'Times New Roman', Times, serif; ">list实现轮换后, map中建立位置与相应字符间的对应。</span>for (int i = 0; i < 3; i++) {
                        //实现轮换if (w[i].empty())continue;k[i] %= (w[i].size());for (int j = 0; j < k[i]; j++) {w[i].push_front(w[i].back());w[i].pop_back();}
                        //遍历对应map<int, char>::iterator it = gp[i].begin();for (it; it != gp[i].end(); it++) {it->second = *(w[i].begin());w[i].pop_front();//删除列表头元素}}
                //<span style="font-family: 'Times New Roman', Times, serif; ">搜索位置依次输出。</span>for (int i = 0; i < n; i++) {if (gp[0].find(i) != gp[0].end())cout << gp[0][i];else if (gp[1].find(i) != gp[1].end())cout << gp[1][i];else cout << gp[2][i];}cout << endl;}return 0;}

     三组具有相似性,采用大小为三的数组k[3],三组的组内轮换与对应都在for()中完成了,操作更方便。


注:参考了归雾yangchenhao8      博客


补充:

          

List成员函数概观

  • Iterators:
    • list.begin() 回传指向第一个元素的 Iterator。
    • list.end() 回传指向最末元素的下一个位置的 Iterator。
    • list.rbegin() 回传指向最末个元素的反向 Iterator。
    • list.rend() 回传指向第一个元素的前一个位置的反向 Iterator。
  • Capacity/Size:
    • list.empty() 若list内部为空,则回传true值。
    • list.size() 回传list内实际的元素个数。
    • lsit.resize() 重新分派list的长度。
  • Element Access
    • list.front() 存取第一个元素。
    • list.back() 存取最末个元素。
  • Modify methods
    • list.push_front() 增加一个新的元素在 list 的前端。
    • list.pop_front() 删除 list 的第一个元素。
    • list.push_back() 增加一个新的元素在 list 的尾端。
    • list.pop_back() 删除 list 的最末个元素。



0 0
原创粉丝点击