hdu 3364 Lanterns(數學:高斯消元)

典型的開燈關燈問題

行列關係找準就好

數組忘了初始化跪了幾發。。。

代碼如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 100
using namespace std;

int a[MAXN][MAXN];
int b[MAXN][MAXN];

void print(int n) {
    for(int i=1; i<=n; ++i) {
        for(int j=1; j<=n+1; ++j)
            printf("%d ", a[i][j]);
        puts("");
    }
}
   

int gauss(int m, int n) {
    int i, j, k, col, max_r;
    col = 1;
    for(k=1; k<=n&&col<=m; ++k, ++col) {
        max_r = k;
        for(i=k+1; i<=n; ++i) {
            if(a[i][col] > a[max_r][col])
                max_r = i;
        }
        if(max_r != k)
            for(j=1; j<=m+1; ++j)
                swap(a[k][j], a[max_r][j]);
        if(a[k][col] == 0) {
            --k;
            continue;
        }
        for(i=k+1; i<=n; ++i) {
            if(a[i][col]) {
                for(j=col; j<=m+1; ++j)
                    a[i][j] ^= a[k][j];
            }
        }
    }
    //print(n);
    for(int i=k; i<=n; ++i)
        if(a[i][m+1])
            return -1;
    return m+1-k;
}

int main(void) {
    int m, n, T, q, k, x;
    scanf("%d", &T);
    for(int _=1; _<=T; ++_) {
        printf("Case %d:\n", _);
        memset(b, 0, sizeof(b));
        scanf("%d%d", &n, &m);
        for(int i=1; i<=m; ++i) {
            scanf("%d", &k);
            while(k--) {
                scanf("%d", &x);
                b[x][i] = 1;
            }
        }
        scanf("%d", &q);
        while(q--) {
            memcpy(a, b, sizeof(b));
            for(int i=1; i<=n; ++i) {
                scanf("%d", &a[i][m+1]);
            }
            //print(n);
            int ans = gauss(m, n);
            if(ans == -1) puts("0");
            else cout << (1ll<<ans) << endl;
        }
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章