POJ 1830 开关问题

POJ_1830

    可以用高斯消元求矩阵的秩,这样就知道了有x个变元,而这些变元可以取任意值,对于每种情况,其他元会有唯一的解,所以一共就有2^x种方案。

#include<stdio.h>

#include<string.h>

#include<iostream>

#define MAXD 35

using namespace std;

int N, mat[MAXD][MAXD];

void init()

{

    int i, j, k;

    memset(mat, 0, sizeof(mat));

    scanf("%d", &N);

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

        scanf("%d", &mat[i][N]);

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

    {

        scanf("%d", &k);

        mat[i][N] ^= k;

        mat[i][i] = 1;

    }

    for(;;)

    {

        scanf("%d%d", &i, &j);

        if(!i && !j)

            break;

        mat[j - 1][i - 1] = 1;

    }

}

int gauss()

{

    int i, j, k, x, y;

    for(i = j = 0; j < N; i ++, j ++)

    {

        if(mat[i][j] == 0)

        {

            for(k = i + 1; k < N; k ++)

                if(mat[k][j])

                    break;

            if(k == N)

            {

                -- i;

                continue;

            }

            for(y = j; y <= N; y ++)

                swap(mat[i][y], mat[k][y]);

        }

        for(x = i + 1; x < N; x ++)

            if(mat[x][j])

            {

                for(y = j; y <= N; y ++)

                    mat[x][y] ^= mat[i][y];

            }

    }

    for(x = i; x < N; x ++)

        if(mat[x][N])

            return -1;

    return 1 << (N - i);

}

void solve()

{

    int ans = gauss();

    if(ans == -1)

        printf("Oh,it's impossible~!!\n");

    else

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

}

int main()

{

    int t;

    scanf("%d", &t);

    while(t --)

    {

        init();

        solve();

    }

    return 0;

}

你可能感兴趣的:(poj)