本蒟蒻的第一篇题解,如果有什么不足,请dalao轻喷。。。
题意
给出两个数 \(n\) 和 \(m\),求出最小的整数 \(p\),使得 \(p\) \(\notin\) { \(n \oplus 1, n \oplus 2, n \oplus 3, ···, n \oplus m\) } 。
思路
异或
先思考这道题之前,还不如先思考这道题目所要用的符号 \(\oplus\) 有什么性质。
其中,\(\oplus\) 的意思为:两个数在二进制状态下,各个数位对齐,位数不够就在前面补零,若两个数位相同就得 \(1\),不同就得 \(0\)。
比如:$12 \oplus 5 = $,列个竖式
---\(1\) \(1\) \(0\) \(0\)
\(\oplus\) \(0\) \(1\) \(0\) \(1\)
\(=\) \(1\) \(0\) \(0\) \(1\)
\(=\) \(9\)
所以 \(12 \oplus 5 = 9\),我们再举个例子:$12 \oplus 9 = $,不难得出答案为 \(5\)。
因此,我们发现异或的一个性质 \(a \oplus b = c\),也可以转换为 \(a \oplus c = b\)。
解题
经过上面的推导,再看看题目,发现在程序中花括号中的数据可能会毫无规律,而且花括号中都有 \(n\),于是我们考虑将式子转换为:\(n \oplus p\) \(\notin\) { \(1, 2, 3, ···,m\) }
所以题目就可以转化为求一个最小的整数 \(p\),使得 $ n \oplus p > m $。
当然,如果枚举出 \(p\),时间肯定承受不了,所以只能构造出 \(p\)。
分类讨论 :
- \(n_i = m_i = 0\),\(p_i = 0\),因为 \(p\) 要最小,如果 \(p_i = 1\),虽然也能满足 \(n \oplus p > m\),但是 \(p\) 不是最小的。
- \(n_i = 0, m_i = 1\),\(p_i = 1\),同上。
- \(n_i = 1, m_i = 0\),\(p_i = 0\), 且后面全为零,因为这个数为已经大于 \(m_i\) 的这一位了,后面的不管再怎么小也能满足题目要求。
- \(n_i = m_i = 1\),\(p_i = 0\),同 \(1\)。
Code
#include <cstdio>
#include <iostream>
using namespace std;
int n, m;
void Main() {
cin >> n >> m;
m++;
int p = 0;
for (int i = 30; i >= 0; i--) {
if (((1 & (n >> i)) == 0) && ((1 & (m >> i)) == 1)) p = (1 << i) | p;
if (((1 & (n >> i)) == 1) && ((1 & (m >> i)) == 0)) break;
}
cout << p << endl;
}
int main() {
int T;
for (cin >> T; T; T--) Main();
return 0;
}
标签:12,题目,CF1554C,int,最小,Mikasa,oplus,include
From: https://www.cnblogs.com/wuzihe/p/18382768