hdu3006挺不错的一道题

这题还是挺不错的,第一个突破点就是n很大但是m很小,所以能组成的集合最多有2^14种的,枚举这每一种能否构成即可。刚开始的时候是用set存每一个数的,超时,略加改进,用位存储就过掉了。不过我还是算蹭过的,600多ms,应该还能继续用位运算优化。

/*

 * hdu3306/win.cpp

 * Created on: 2012-10-27

 * Author    : ben

 */

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

#include <ctime>

#include <iostream>

#include <algorithm>

#include <queue>

#include <set>

#include <map>

#include <stack>

#include <string>

#include <vector>

#include <deque>

#include <list>

#include <functional>

#include <numeric>

#include <cctype>

using namespace std;

const int MAXN = 105;

int sets[MAXN];

bool used[MAXN];

int N, M, ans;

void init() {

    int J, t;

    fill(sets, sets + N, 0);

    for(int i = 0; i < N; i++) {

        scanf("%d", &J);

        for(int j = 0; j < J; j++) {

            scanf("%d", &t);

            sets[i] += (1 << t);

        }

    }

}

bool judge_state(int state) {

    fill(used, used + N, true);

    int s = state;

    for(int i = 1; i <= M; i++) {

        if(s % 2 == 0) {

            for(int j = 0; j < N; j++) {

                if((sets[j] & (1 << i))) {

                    used[j] = false;

                }

            }

        }

        s >>= 1;

    }

    s = state;

    for(int i = 1; i <= M; i++) {

        if(s % 2 == 1) {

            int j = 0;

            for(; j < N; j++) {

                if(used[j] && (sets[j] & (1 << i))) {

                    break;

                }

            }

            if(j >= N) {

                return false;

            }

        }

        s >>= 1;

    }

    return true;

}

int main() {

#ifndef ONLINE_JUDGE

    freopen("data.in", "r", stdin);

#endif

    while(scanf("%d%d", &N, &M) == 2) {

        init();

        ans = 0;

        for(int state = 1; state < (1 << M); state++) {

            if(judge_state(state)) {

                ans++;

            }

        }

        printf("%d\n", ans);

    }

    return 0;

}

你可能感兴趣的:(HDU)