原题:
题目意思是: 给定数列a,交换任意两个数的任意两位(二进制表示,也就是1,或者0),求执行若干次操作后数列中的最大值和最小值的差
思路: 直接把数列a中所有数都转换为二进制数,依次统计每个数中1的数量,例如第i位上为1的数量用b[i]表示,b[i]最大是n,最小是0
对于每一个b[i],有以下规律:
(1)如果统计得到的b[i]为n,说明所有数字上的这一位都为0,那么无论进行多少次变换得到的最终结果转换为二进制后,这一位上仍然为1。
(2)如果统计得到的b[i]为0,说明所有数字上的这一位都为0,不进行操作。
(3)如果统计得到的b[i]不为0,即1 <= b[i] <= n-1
说明这一位可以经过变换为1,也可以变换为0
那么
对于最小值,如果统计得到的a[i]为n,说明数列a中的每个数的这一位都为1,不论怎么经过变换都无法消去这位上的1。所以加上pow(2,i);
对于最大值,如果统计得到的a[i]不为0,说明可以经过变换使得最大值的这一位为1。所以加上pow(2,i);
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define de(x) cout << x << " ";
#define sf(x) scanf("%d", &x);
#define Pu puts("");
const int N = 1e5 + 10;
int n, m;
int a[N];
int main() {
int T;
cin >> T;
while (T--) {
cin >> n;
memset(a, 0, sizeof(a));
int x;
for (int i = 1; i <= n; i++) {
sf(x);
int tot = 0;
while (x) {
if (x % 2 == 1)
a[tot]++;
tot++;
x /= 2;
}
}
int l = 0, r = 0;
for (int i = 0; i < 13; i++) {
if (a[i] == n) {
l += pow(2, i);
r += pow(2, i);
}
if (a[i] > 0 && a[i] < n) {
r += pow(2, i);
}
}
de(r - l);
}
}