Time Limit: 3 second
Memory Limit: 2 MB
假定涉及的是英文句子,且仅由英文大写字母、逗号、句点和空格符组成,例如:ON A CLEAR DAY,YOU CAN SEE FOREVER
编码代码如下:
先输入一个正整数n(1<=n<=26),它与某个英文大写字母相对应,比如n=9对应字母I。这个字母确定了对原句中英文字母的转换,如原码是ABCDEFG,转换码是IJKLMNO,其他字符则不变。因此原句转换成:WV I K TMIZ LIG,GWC KIV AMM NMZMDMZ,为了使得较难破译,特将上述转换后的信息在自左向右两两字符交换,若最后剩下单个字符则不换。然后,将一开始表示转换关系的字母置于前面,便产生了最后的编码:IVWI K MTZIL GIG,CWK VIA MMN ZWDMZM。
Input
输入一串英文句子(由英文大写字母、逗号、句点和空格符组成)和整数n(1<=n<=26):
再输入一行经过编码处理的最后编码
第一行输入英文句子。
第二行输入整数n的值。
第三行输入经过编码处理后的编码
Output
输出编码结果和译码结果:
第一行输出最后的编码。
第二行输出译码结果。
Sample Input
ON A CLEAR DAY,YOU CAN SEE FOREVER 9 IFAJKAHUHZ ZJL?
Sample Output
IVWI K MTZIL GIG,CWK VIA MMN ZWDMZM SXCBZSZM RBR?D
【题解】
用c++的加法,int 和 char的互换,可以很快解决字母的转化.大于'Z'的时候再重新转化成'A',一步一步转化.可以弄一个过程,1代表忘后转化,而2代表往前转化字母。、
换位只要for到偶数位,然后和前面一个换位就好。奇数位就换,可能会有剩下一个的情况。会出错。
string类可以加减法,key加上去很简单。取出来用substr函数(1,2),表示从1开始截取两位string类
会有空格,cin函数不能读取空格,虽然在一行,但后面一段会被忽略。要用cin.getline(char类数组,char数组的大小),先把输入的东西整行输入char数组,之后
string s1 = string(char类数组),强制转化成string类.
【代码】
#include <cstdio> #include <iostream> #include <string> using namespace std; string s1,s2; int n,ls1,ls2; void input_data() { char ts1[300]; //先定义一个char 数组,用来存储整行输入的字符 cin.getline(ts1,300); s1 = string(ts1); //转换成string类 cin >> n; cin.get();//这里要用一个get函数,不然读取不了第3行。应该是getline函数必须要用到的。 char ts2[300]; cin.getline(ts2,300); s2 = string(ts2); ls1 = s1.size(); //string.size()表示字符串的长度 ls2 = s2.size(); } void chan_ge(char &z,int k,int d) //change 函数(z表示要变的单个字符,k表示key秘钥,d表示改变的方向) { if (d == 0) //正向改变 { z+= (k-1); if (z > 'Z') z = 'A' + z - 'Z'-1; //超过Z的处理方法 } //反向改变 else { z-= (k-1); if (z < 'A') //小于A的处理方法 z = 'Z'-('A'-z-1); } } void ex_change( char &a,char &b) //交换位置 注意要加& { char t =a; a = b; b = t; } void get_ans() { for (int i = 0 ; i < ls1;i++) //字符串是从0开始计数 if ((s1[i] <= 'Z') && (s1[i] >= 'A')) //如果这个字符是字母 chan_ge(s1[i],n,0); //转换 for (int i = 0 ; i < ls1;i++) //是奇数(字符串是从0) if ( (i % 2) == 1) ex_change(s1[i],s1[i-1]); char key = 'A' + n -1; s1 = key + s1; //把秘钥加到字符串的开头 n = s2[0] - 'A' +1; //取出秘钥 s2 = s2.substr(1,ls2-1); //截取开头的秘钥 ls2--; for (int i = 0;i < ls2;i++) //同样交换 if ( (i % 2) == 1) ex_change(s2[i],s2[i-1]); for (int i = 0;i < ls2;i++) if ((s2[i] <= 'Z') && (s2[i] >= 'A')) //判断为字母后反向转换。 chan_ge(s2[i],n,1); } void output_ans() { cout << s1 << endl; cout << s2; } int main() { //freopen("E:\rush.txt","r",stdin); input_data(); get_ans(); output_ans(); return 0; }