题目链接
参考博客
- a和b二进制不相同的位数为奇数时才有解
- 相邻的两个数的二进制有且仅有一位不同,递推可知a和b的二进制有奇数位不同
- 如果a和b的二进制有奇数位不同,则选出不同的一位x,除去这一位之后还有偶数位不同,变为a'和b',把a'改变一位变为mid,这样a'和mid、mid和b'都有奇数位不同。递归构造(a',mid),(mid,b'),再把第x位补回来,前半部序列第x位与a相同,后半部与b相同。
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 100;
const int inf = 0x3f3f3f3f;
const int SZ = 1 << 20; //快速io
struct fastio {
char inbuf[SZ];
char outbuf[SZ];
fastio() {
setvbuf(stdin, inbuf, _IOFBF, SZ);
setvbuf(stdout, outbuf, _IOFBF, SZ);
}
} io;
void read(int &x) {
x = 0;
char ch, c = getchar();
while (c < '0' || c > '9') ch = c, c = getchar();
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
if (ch == '-') x = -x;
}
int vis[30];
int n;
void dfs(int k, int a, int b) {
if (k == 1) {
printf("%d %d ", a, b);
return;
}
for (int i = 0; i < n; i++) {
if (((a >> i) & 1) ^ ((b >> i) & 1)) {
vis[i] = 1;
int mid = a;
for (int j = 0; j < n; j++) {
if (!vis[j]) {
mid = mid ^ (1 << j);
break;
}
}
dfs(k - 1, a, mid);
dfs(k - 1, mid ^ (1 << i), b);
vis[i] = 0;
break;
}
}
}
int main() {
//freopen("in.txt", "r", stdin);
int a, b;
cin >> n >> a >> b;
if (__builtin_popcount(a ^ b) % 2 == 0) {
printf("NO
");
} else {
printf("YES
");
dfs(n, a, b);
}
return 0;
}