首页 > 代码库 > POJ1830开关问题——gauss消元

POJ1830开关问题——gauss消元

题目链接

  • 分析:
    第一个高斯消元题目,操作是异或。奇偶能够用0、1来表示,也就表示成bool类型的方程,操作是异或。和加法没有差别
    题目中有两个未知量:每一个开关被按下的次数(0、1)、每一个开关的转换次数。

    题目仅仅和操作次数的奇偶有关,所以用0、1表示之后,对于每一个开关的转换次数就已经知道了。所以仅仅有一个未知量。能够线性表示。练习使用模板

const int maxn = 40;

int a[maxn][maxn];
int gauss(int N, int M)
{
    int r, c, pvt;
    bool flag;
    for (r = 0, c = 0; r < N && c < M; ++ r, ++ c) {
        flag = false;
        for (int i = r; i < N; ++ i)
            if (a[i][c]) {
                flag = a[pvt=i][c];
                break;
            }
        if (!flag) {
            r--; continue;
        }
        if (pvt != r)
            for (int j = r; j <= M; ++j) swap(a[r][j], a[pvt][j]);
        for (int i = r+1; i < N; ++i)
            if(a[i][c])
            {
                a[i][c] = false;
                for (int j = c+1; j <= M; ++j) {
                    if(a[r][j]) a[i][j] = !a[i][j];
            }
        }
    }
    for (int i = r; i < N; ++i)
        if (a[i][M]) return -1;
    if (r < M) return M-r;
    for (int i = M-1; i >= 0; --i)
    {
        for (int j = i+1; j < M; ++j)
            a[i][M] ^= a[j][M]*a[i][j];
        a[i][M] &= a[i][i];
    }
    return 0;
}

int main()
{
    //    freopen("in.txt", "r", stdin);
    int T, n, x, y;
    RI(T);
    FE(kase, 1, T)
    {
        RI(n);
        CLR(a, 0);
        REP(i, n) RI(a[i][n]);
        REP(i, n)
        {
            int t;
            RI(t);
            a[i][n] ^= t;
            a[i][i] = 1;
        }
        while (RII(x, y) && x)
        {
            a[y - 1][x - 1] = 1;
        }
        int ans = gauss(n, n);
        if (ans == -1)
            puts("Oh,it‘s impossible~!!");
        else
            WI(1 << ans);
    }
    return 0;
}


POJ1830开关问题——gauss消元