共计 963 个字符,预计需要花费 3 分钟才能阅读完成。
前几天听一个学长描述了一下他做的几道头条笔试题,自己空闲时间选了一道简单的尝试做了做,由于没有经过校验,答案能对多少,自己也没数,因此读者就当看个乐子,答案是当不得真的。
题目描述
两个人通过加密通信的方式进行通信,每条信息都被编译成二进制数 B(明文),其长度为 N。信息被写下 K 次,每次向右移动 0,1,……,k- 1 位。
例如
B=1001010, K=4
1001010
1001010
1001010
1001010
然后对每一列进行异或操作,结果称为 S(密文)
上面的结果就为
1110100110
要求是写一个程序去实现这种编码的解密过程
输入
第一行两个整数 N 和 K
第二行一个二进制字符串 S,长度为 N +K-1
输出
输出明文 B
解题思路
首先要明白异或运算是干嘛的
异或运算:两个数相等就置 0,不等就置 1。
所以可以看成参与运算的 1 的数量是单数还是偶数
再次可以知道 B 的长度为 N
然后很明显 B 的第一位和最后一位就等于 S 的第一位和最后一位。
private static byte[] decrypt(int N, int K, byte[] S) {byte[] answer = new byte[N];
answer[0] = S[0];
answer[N - 1] = S[S.length - 1];
}
可以看出 计算部分要分为两种情况,计算第i
位答案时:
如果
i < k
就需要和前面k - i
个答案进行运算
如果i >= k
就需要和前面k
个答案进行运算
解码的完整代码如下
private static byte[] decrypt(int N, int K, byte[] S) {byte[] answer = new byte[N];
answer[0] = S[0];
answer[N - 1] = S[S.length - 1];
for (int i = 1; i < N - 1; i++) {
int count = 0;
int temp; // 用于存储循环次数
if (i < K) {
temp = K - i;
// 前 K 个结束
} else {temp = K;}
for (int j = 0; j < temp; j++) {if (answer[j] == 1)
count++;
}
if (count % 2 == 1) {if (S[i] == 1) {answer[i] = 1;
} else {answer[i] = 0;
}
} else {if (S[i] == 1) {answer[i] = 0;
} else {answer[i] = 1;
}
}
}
return answer;
}
正文完