AGC031 C

题目链接

参考博客

  • 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;
}
原文地址:https://www.cnblogs.com/albert-biu/p/10987033.html