Solution of P15445
Update Catelog
题目描述
题目给出 $Q$ 次询问,每一次询问为是否有 $(a,b)$ 满足$\left{\begin{aligned}a\operatorname{or}b=x\a+b\leq z\|a-b|\leq y\end{aligned}\right.$。
思路表述
20分做法
枚举 $(x, y)$ 二元组,满足 $1\leq x, y \leq z$,有即Yes,无即No。
难度:入门
#include <bits/stdc++.h>
using namespace std;
const string ans[2] = {"NO", "YES"};
bool solve(int x, int y, int z) {
// a or b=x, |a-b|<=y,a+b<=z
for (int a = 0; a <= z; a ++)
for (int b = 0; b <= z - a; b ++)
if ((a | b) == x && abs(a - b) <= y)
return 1;
return 0;
}
int main() {
int T;
cin >> T;
while (T --){
int x, y, z;
cin >> x >> y >> z;
cout << ans[solve(x, y, z)] << endl;
}
return 0;
}
时间复杂度:$O(T\cdot z^2)$
50分做法
(我在考场上想的,不保证完全正确)
考虑贪心,当 $z\geq 2x$ 时,就只需要考虑 $(a, b)$ 的差。
最小的差就是 $lowbit(x)$。
额,就加了几行优化 而已 嘛。
#include <bits/stdc++.h>
using namespace std;
const string ans[2] = {"NO\n", "YES\n"};
bool solve(int x, int y, int z) {
for (int a = 0; a <= z; a ++)
for (int b = 0; b <= z - a; b ++)
if ((a | b) == x && abs(a - b) <= y && a != b)
return 1;
return 0;
}
int lowbit(int x) {
return x & -x;
}
signed main() {
int T;
cin >> T;
while (T --){
int x, y, z;
cin >> x >> y >> z;
if (z >= (2 * x) && x >= 5e3) {
if (lowbit(x) > y)
cout << ans[0];
else
cout << ans[1];
continue;
}
// n^2
cout << ans[solve(x, y, z)];
}
return 0;
}
满分做法
依然考虑贪心。
看图吧。

代码:
#include <bits/stdc++.h>
using namespace std;
const string ans[2] = {"NO\n", "YES\n"};
bool solven2(int x, int y, int z) {
// a or b=x, |a-b|<=y,a+b<=z
for (int a = 0; a <= z; a ++)
for (int b = 0; b <= z - a; b ++)
if ((a | b) == x && abs(a - b) <= y && a != b)
return 1;
return 0;
}
int lowbit(int x) {
return x & -x;
}
int fx(int x) { // 查找比x小的最大的2^k的值与x-a的差
int ans = 1;
for (;ans <= x; ) ans <<= 1;
ans >>= 1;
return ans - (x - ans);
}
signed main() {
int T;
cin >> T;
while (T --){
int x, y, z;
cin >> x >> y >> z;
// z>=2x
if (z >= (2 * x) && x >= 5e3) {
if (lowbit(x) > y)
cout << ans[0];
else
cout << ans[1];
continue;
}
// n^2
if (x <= 5000) {
cout << ans[solven2(x, y, z)];
continue;
}
if (z < x) {
cout << ans[0]; // Is it possible?????
continue;
}
if (fx(x) <= y) {
cout << ans[1];
continue;
}
int sum = 0;
bool flg = 0;
for (int i = 60; i >= 0; i --)
if ((x >> i) & 1) {
sum |= (1ll << i);
if (fx(x - sum) <= y && x + sum <= z) {
flg = 1;
break;
}
}
cout << ans[flg];
}
return 0;
}
(求管理员大大给过)
浙公网安备 33010602011771号