Codeforces Round #485 (Div. 1) C

用了很神奇的办法,对于每一个数,取反,暴力找它所有子集,如果dfs到的数字又是我们输入的数字,就继续取反暴力找子集

#include <bits/stdc++.h>
using namespace std;
const int N = (1 << 23) + 10;
int a[N];
bool vis[N];
int flag[N];
int n, m;
void dfs(int u) {
    //printf("%d
", u);
    vis[u] = true;
    if (flag[u] == 1 && !vis[u ^ ((1 << (n + 1)) - 1)])
        dfs(u ^ ((1 << (n + 1)) - 1));
    for (int i = 0; i <= n; i++)
        if ((u & (1 << i)) && !vis[u - (1 << i)])
            dfs(u - (1 << i));
}
int main() {
    scanf("%d %d", &n, &m);
    int ans = 0;
    for (int i = 1; i <= m; i++) {
        scanf("%d", &a[i]);
        flag[a[i]] = 1;                                                                      
    }
    for (int i = 1; i <= m; i++) {
        if (vis[a[i]])    continue;
        flag[a[i]] = 2;
        dfs(a[i] ^ ((1 << (n + 1)) - 1)); 
        ans++;
    }
    printf("%d
", ans);
    return 0;
}
原文地址:https://www.cnblogs.com/cminus/p/14094098.html