【牛客编程巅峰赛S1第8场】playfair
playfair
https://ac.nowcoder.com/acm/problem/207928
题目
牛牛用 playfair 加密信息。加密过程中的 都由 来代替。
playfair 加密算法首先需要绘制密码表,密码表是一个 的矩阵,开始由密钥按顺序排列,其余按照未出现的字母顺序。若密钥中含有重复字母需要将重复字母去掉,若有 用 来代替。
加密明文需要符合以下规则:
将明文中每两个字母组成一对,若成对后是两个相同字母或留下一个字母无法成对,则不进行变化直接放入密文中。
明文对 在同一行,对应密文对 分别为紧靠 右端的字母,最后一列右端对应第一列。
明文对 在同一列,对应密文对 分别为紧靠 下方的字母,最后一行下方对应第一行。
明文对 不在同一行且不在同一列,对应密文对 分别为 确定的矩形中的同行另外两角。
现在给定密钥和明文,求出密文是什么吗?
解题思路
根据给定的密钥 绘制密码表。
使用 记录字符在密码表中的位置。使用 记录密码表中每个位置上的字符。
然后按照加密明文规则对明文 求出密文。
注意用字符 替代字符 。
C++代码
class Solution { public: /** * playfair加密算法 * @param key string字符串 密钥 * @param str string字符串 明文 * @return string字符串 */ string Encode(string key, string str) { // write code here int vis[26] = {0}; map<char, pair<int,int>> pos; vector<vector<char>> matrix(5, vector<char>(5)); int row = 0; int col = 0; for(auto c : key){ if(c == 'j') c = 'i'; int index = c - 'a'; if(!vis[index]){ vis[index] = 1; pos[c] = make_pair(row, col); matrix[row][col] = c; ++col; if(col==5){ col = 0; ++row; } } } vis['j'-'a'] = 1; for(int i=0; i<26; ++i){ if(!vis[i]){ char ch = i + 'a'; pos[ch] = make_pair(row, col); matrix[row][col] = ch; ++col; if(col==5){ col = 0; ++row; } } } for(int i=1; i<str.size(); i+=2){ if(str[i-1]=='j') str[i-1]='i'; if(str[i]=='j') str[i]='i'; int c1 = str[i-1]; int c2 = str[i]; if(c1==c2) continue; int x1 = pos[c1].first; int y1 = pos[c1].second; int x2 = pos[c2].first; int y2 = pos[c2].second; if(x1==x2){ y1 = (y1+1)%5; y2 = (y2+1)%5; str[i-1] = matrix[x1][y1]; str[i] = matrix[x2][y2]; } else if(y1==y2){ x1 = (x1+1)%5; x2 = (x2+1)%5; str[i-1] = matrix[x1][y1]; str[i] = matrix[x2][y2]; } else{ str[i-1] = matrix[x1][y2]; str[i] = matrix[x2][y1]; } } return str; } };