1036. Crypto Columns
Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
The columnar encryption scheme scrambles the letters in a message (or plaintext) using a keyword as illustrated in the following example: Suppose BATBOY is the keyword and our message is MEET ME BY THE OLD OAK TREE. Since the keyword has 6 letters, we write the message (ignoring spacing and punctuation) in a grid with 6 columns, padding with random extra letters as needed:
MEETME
BYTHEO
LDOAKT
REENTH
Here, we've padded the message with NTH. Now the message is printed out by columns, but the columns are printed in the order determined by the letters in the keyword. Since A is the letter of the keyword that comes first in the alphabet, column 2 is printed first. The next letter, B, occurs twice. In the case of a tie like this we print the columns leftmost first, so we print column 1, then column 4. This continues, printing the remaining columns in order 5, 3 and finally 6. So, the order the columns of the grid are printed would be 2, 1, 4, 5, 3, 6, in this case. This output is called the ciphertext, which in this example would be EYDEMBLRTHANMEKTETOEEOTH. Your job will be to recover the plaintext when given the keyword and the ciphertext.
Input
There will be multiple input sets. Each set will be 2 input lines. The first input line will hold the keyword, which will be no longer than 10 characters and will consist of all uppercase letters. The second line will be the ciphertext, which will be no longer than 100 characters and will consist of all uppercase letters. The keyword THEEND indicates end of input, in which case there will be no ciphertext to follow.
Output
For each input set, output one line that contains the plaintext (with any characters that were added for padding). This line should contain no spacing and should be all uppercase letters.
Sample Input
BATBOY
EYDEMBLRTHANMEKTETOEEOTH
HUMDING
EIAAHEBXOIFWEHRXONNAALRSUMNREDEXCTLFTVEXPEDARTAXNAARYIEX
THEEND
Sample Output
MEETMEBYTHEOLDOAKTREENTH
ONCEUPONATIMEINALANDFARFARAWAYTHERELIVEDTHREEBEARSXXXXXX
這題有點坑,開始壓根就沒能了解清究竟是怎麼加密的一個過程,原諒我的了解能力有限。其實就是根據key中的字母大小順序來決定密文輸出的列,比如key[1] = A, 那第1+1=2 列就是第一個輸出的列,然後key[0] = B , 是以第1列是第二個輸出的列,key[3] = B ,故第3+1=4列是第三個輸出的列,key[4] = O ,是以第4+1=5列是第四個輸出的列,如此規則。
解題思路,模拟整個過程。記錄key中字母所代表的列數,然後對其進行字典順序排好,将密文填進加密矩陣,然後按順序輸出。over
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
struct node
{
int index;
char ch;
};
bool cmp(const node a, const node b)
{
return a.ch < b.ch;
}
int main()
{
string key;
string ciphertext;
struct node keyNode[11];
char text[10][10];
while(cin>>key && key!="THEEND")
{
int keyLen = key.size();
for(int i=0; i<keyLen; i++)
{
keyNode[i].index = i;
keyNode[i].ch = key[i];
}
//對輸入的key進行按照字典順序排序,記錄它的列号
sort(keyNode, keyNode+keyLen, cmp);
cin>>ciphertext;
int textLen = ciphertext.size();
int tmp = 0;
//模拟加密過程按列重新填寫矩陣
for(int i=0; i<textLen; )
{
for(int j=0; j<textLen/keyLen; j++)
{
text[j][ keyNode[tmp].index ] = ciphertext[i++];
}
tmp ++ ;
}
//按照從左上到右下的順序列印出來
for(int i=0; i<textLen/keyLen; i++)
{
for(int j=0; j<keyLen; j++)
cout<<text[i][j];
}
cout<<endl;
}
//system("pause");
return 0;
}