前言
异或运算:是一种在二进制数系统中使用的逻辑运算。它的基本规则是对两个二进制位进行比较,如果这两个位不同,则结果为 \(1\);如果相同,则结果为 \(0\)。
异或运算的规则
- \(0\) XOR \(0\) = \(0\)
- \(0\) XOR \(1\) = \(1\)
- \(1\) XOR \(0\) = \(1\)
- \(1\) XOR \(1\) = \(0\)
特性
- 自反性:任何数与自身进行异或运算的结果均为 \(0\)
- 零和性:任何数与 \(0\) 进行异或运算都是其本身
- 交换律:异或运算符合交换律,即 \(a\) XOR \(b\) = \(b\) XOR \(a\)
- 结合律:异或运算符合结合律,即 (\(a\) XOR \(b\)) XOR \(c\) = \(a\) XOR (\(b\) XOR \(c\))
题意
https://codeforces.com/problemset/problem/1151/B
输入一个 \(n \times m(1 \leq n, m \leq 500)\) 的矩阵 \(a(0 \leq a_{i,j} \leq 1023)\)。
若你能在每一行找出一个数,并且使得这些数异或的结果严格大于 \(0\),则输出 \(TAK\),并在下一行输出每一行选择的列号;否则输出 \(NIE\)。
题解
要使得 \(n\) 个数的异或值严格大于 \(0\),那么只需要使得其中一个二进制位的异或结果不为 \(0\)即可。
根据异或运算的特性,易知同一个二进制位上 \(1\) 的个数若为奇数,那么该位最后的计算结果必定为 \(1\)。
参考代码
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
using namespace std;
constexpr int N = 507;
int n, m;
int a[N][N];
vector<int> zero[N][10], one[N][10];
int main() {
IOS
cin >> n >> m;
for (int i = 1; i <= n; ++ i) for (int j = 1; j <= m; ++ j) cin >> a[i][j];
//只要让某一位的异或不为0,结果就必定不为0
for (int i = 0; i < 10; ++ i) {
int p = 0, q = 0;
for (int j = 1; j <= n; ++ j) {
for (int k = 1; k <= m; ++ k) {
if (a[j][k] >> i & 1) one[j][i].emplace_back(k);
else zero[j][i].emplace_back(k);
}
if (one[j][i].size() == 0) p ++;
else if (one[j][i].size() == m) q ++;
}
int r = n - p - q;
if ((q & 1) || r > 0) {
cout << "TAK\n";
bool flag = q & 1 ? false : true;
for (int j = 1; j <= n; ++ j) {
int sz = one[j][i].size();
if (sz == 0 || sz == m) cout << "1 ";
else if (flag) {
cout << one[j][i].front() << ' ';
flag = false;
} else cout << zero[j][i].front() << ' ';
}
return 0;
}
}
cout << "NIE\n";
return 0;
}
标签:Dima,XOR,运算,int,异或,leq,Bad,二进制位
From: https://www.cnblogs.com/RomanLin/p/18568266