字节跳动研发2019年(2020届)笔试题(2)-字符解密
问题描述:
每条信息都被编译成二进制数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 }

浙公网安备 33010602011771号