CF2153B Bitwise Reversion | 数学 | 模拟

CF2153B Bitwise Reversion | 数学 | 模拟

题目描述

给定三个非负整数 \(x\)\(y\)\(z\),判断是否存在三个非负整数 \(a\)\(b\)\(c\),满足以下三个条件:

  • \(a \mathbin{\&} b = x\)
  • \(b \mathbin{\&} c = y\)
  • \(a \mathbin{\&} c = z\)

其中 \(\mathbin{\&}\) 表示按位与运算。

数据范围

输入包含多组测试数据。第一行包含一个整数 \(t\)\(1 \leq t \leq 10^4\)),表示测试数据的组数。

接下来每组测试数据占一行,每行包含三个整数 \(x\)\(y\)\(z\)\(0 \leq x, y, z \leq 10^9\)),分别表示 \(a \mathbin{\&} b\)\(b \mathbin{\&} c\)\(a \mathbin{\&} c\) 的目标值。

5
1 1 1
3 2 6
4 8 12
9 10 12
12730 3088 28130
YES
YES
NO
YES
NO

题解及证明过程

我们知道 \(x_i,y_i,z_i \in \left\{ 0,1\right\}\)\(a_i,b_i,c_i \in \left\{ 0,1\right\}\),为了找出满足 \(a \mathbin{\&} b = x\)\(b \mathbin{\&} c = y\)\(a \mathbin{\&} c = z\) 的数,我们尝试通过排列组合所有情况。

可知对于一组 \((a_i,b_i,c_i)\)\(8\) 种情况。排列组合后后算出对应的 \(x_i,y_i,z_i\) 的值即可。如下:

\(a_i\) \(b_i\) \(c_i\) \(x_i\) \(y_i\) \(z_i\)
\(0\) \(0\) \(0\) \(0\) \(0\) \(0\)
\(1\) \(0\) \(0\) \(0\) \(0\) \(0\)
\(0\) \(1\) \(0\) \(0\) \(0\) \(0\)
\(0\) \(0\) \(1\) \(0\) \(0\) \(0\)
\(1\) \(1\) \(0\) \(1\) \(0\) \(0\)
\(0\) \(1\) \(1\) \(0\) \(1\) \(0\)
\(1\) \(0\) \(1\) \(0\) \(0\) \(1\)
\({\color{Red} 1}\) \({\color{Red} 1}\) \({\color{Red} 1}\) \({\color{Red} 1}\) \({\color{Red} 1}\) \({\color{Red} 1}\)

由表可知,如果 \(x_i=1\)\(y_i=1\),则一定有 \(z_i=1\)。如果 \(x_i=1\)\(z_i=1\),则一定有 \(y_i=1\)。如果 \(y_i=1\)\(z_i=1\),则一定有 \(x_i=1\)

我们同样可以用本文中的要求来证明。根据 \(a \mathbin{\&} b = x\)\(b \mathbin{\&} c = y\)\(a \mathbin{\&} c = z\),所以当 \(x_i=1\)\(y_i=1\) 时,\(a_i=b_i=1\)\(b_i=c_i=1\),所以 \(a_i=c_i=1\),此时代入 \(a \mathbin{\&} c = z\),则 \(z_i=a_i \mathbin{\&} c_i =1\mathbin{\&} 1=1\),故定理成立。同理可证明其他两个结论。

因为 \(0 \leq x, y, z \leq 10^9\),所以我们直接遍历前 \(30\)(因为 \(\log_2 (10^9)\approx 30\))个二进制位。使用布尔形型变量检查其是否满足标准即可。注意数组下标从 \(0\) 开始。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll T,x,y,z;
int main(){
    cin>>T;
    while(T--){
        cin>>x>>y>>z;
        bool f=1;
        for(int i=0;i<31;i++){
            ll x2=(x>>i)&1,y2=(y>>i)&1,z2=(z>>i)&1;
            if(x2&y2&&!z2){f=0; break;}
            if(x2&z2&&!y2){f=0; break;}
            if(y2&z2&&!x2){f=0; break;}
        }
        if(f) cout<<"Yes\n";
        else cout<<"No\n";
    }
    return 0;
}
posted @ 2025-11-01 17:56  M1_Byte  阅读(9)  评论(0)    收藏  举报