问题描述:
每条信息都被编译成二进制数B(明文),其长度为N。然后该信息被写下K次,每次向右移动0,1,...,K-1位。
例如 B= 1001010, K=4;
1001010
1001010
1001010
1001010
对每一列进行异或操作,并且把最终结果记录下来,将该数称为密文,上述例子的结果为1110100110
最后将编码的信息S和K发送给对方;
写一个程序去实现密文的解密过程。
输入描述:第一行输入两个整数N和K,
第二行输入一个二进制字符串S,长度是N+K-1;
输出描述:输出明文B
示例:
输入: 7 4
1110100110
输出: 1001010
解题思路:
1、 异或的性质
如果c = a^b,那么b = a^c
2、 分为两种情况
i<K时
S[0] = B[0] ===> B[0] = S[0]
S[1] = B[0]^B[1] ===> B[1] = S[1]^B[0] = S[1] ^ S[0]
S[2] = B[0]^B[1]^B[2] ===> B[2] = S[2]^(B[0]^B[1])= S[2]^S[1]
S[k-1] = B[0]^...^B[k-1] ===> B[k-1] = S[k-1]^S[k-2]
i>=K时
S[i] = B[i-k+1]^B[i-k+2]^...B[i]
S[i+1] = B[i-k+2]^...B[i]^B[i+1] ===> B[i-k+1] ^ S[i+1] = S[i] ^ B[i+1]
为了方便理解,令j=k+1,有:
B[j-k] ^ S[j] = S[j-1] ^ B[j] ===> B[j] = S[j] ^ S[j-1] ^ B[j-k] //性质1,以及异或运算符合交换律
3、由于S时字符串,还需要写一个字符的异或运算
参考代码:(在做题的时候没有解出来,这是后面写的,通过了他提供的测试用例,但是不确定是否能通过所有测试,如有错误,欢迎大家指导交流)
1 #include <iostream>
2 #include <string>
3 using namespace std;
4
5 char charBit(char a, char b) {
6 if (a == b)
7 return ‘0‘;
8 else
9 return ‘1‘;
10 }
11
12 int main()
13 {
14 int n, k;
15 cin >> n >> k;
16 string s;
17 cin >> s;
18 char* b = new char[n + 1];
19 b[0] = s[0];
20 for (int i = 1; i < n; i++) {
21 if (i < k) {
22 b[i] = charBit(s[i - 1], s[i]);
23 cout << i << " : " << b[i] << endl;
24 }
25 else
26 {
27 b[i] = charBit(charBit(s[i], s[i - 1]), b[i - k]);
28 cout << i << " : " << b[i] << endl;
29 }
30 }
31 b[n] = ‘\0‘;
32 cout << b << endl;
33 }
字节跳动研发2019年(2020届)笔试题(2)-字符解密
原文:https://www.cnblogs.com/wzycoding/p/11342150.html