C. XOR-distance
题意:给定x,y和r,现在要选一个数v,问最小化的abs((x ^ v) - (y ^ v))的数值是多少。
思路:令x为两个数中较大的一个,然后找到第一个x出现而y未出现的高位,随后从该高位的下一个位置开始,遍历剩下的低位,看是否有x出现而y未出现的位置,如果有,这个位置就纳入考虑的bit位。最后,将所有考虑的bit位进行贪心求和,找出最大的v即可。
总结:今天的题做的很顺,这里再重新捋一下思路。首先,这类问题一定是从二进制的角度考虑,其次,考虑操作的特性,如果两个数同时xor一个相同的数,那么如果这两个数的bit位相同,那么xor后再相减没有意义,所以能够缩小他们的差值的异或值,必须能够让小的数的bit位打开,而大的数的bit位关闭,随后在这个bit位上的相减,就需要大的数向更高位来借位,从而达到消耗高位bit位的效果。最后选出bit位后,怎么确定v?一开始想的暴力破解,但是时间复杂度太高,因为bit位可能有60多个,严重TLE,dp好像也不行,最后考虑了一下,所有的bit位的数值都是2的整数次方,所以只要贪心的考虑最大的bit位即可,优先大bit,随后小bit,比如r不超过9,那肯定8 + 1划算,而不是4 + 2 + 1
inline void solve() {
long long x, y, r;
cin >> x >> y >> r;
if (x < y) {
swap(x, y);
}
int s = -1;
for (int i = 62; i >= 0; --i) {
auto v = (1ll << i);
if ((v & (x)) && !(v & y)) {
s = i;
break;
}
}
if (s == -1) {
cout << 0 << '\n';
return;
}
vector<int> nums;
for (int i = s - 1; i >= 0; --i) {
auto v = (1ll << i);
if ((x & v) && !(y & v)) {
nums.push_back(i);
}
}
long long v = 0;
for (const auto& i : nums) {
if (v + (1ll << i) <= r) {
v += (1ll << i);
}
}
cout << (std::abs((x ^ v) - (y ^ v))) << '\n';
}

浙公网安备 33010602011771号