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;
}

满分做法

依然考虑贪心。

看图吧。

image

代码:

#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;
}

(求管理员大大给过)

posted on 2026-02-26 11:00  tom023sss  阅读(17)  评论(0)    收藏  举报