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;
}
posted @ 2012-10-27 14:23  moonbay  阅读(137)  评论(0编辑  收藏  举报