Loading

POJ1830 开关问题 高斯消元 异或

设xixi表示第ii个开关的操作情况,那么xi=1xi=1为按了这个开关,否则xi=0xi=0表示这个开关并没有按下去,那么我们接着统计ai,jai,j表示第i个开关和第j个开关的联系情况,ai,j=1ai,j=1表示按下j会影响i的状态,否则就是不会影响,即ai,j=0ai,j=0,特殊地一个点就是,ai,i=1ai,i=1,因为我们本身肯定会影响本身.

 

这里由于系数是1,0,直接进行状态压缩。

高斯消元过程种,把加法,减法替换成异或,不执行乘法,最终可以得到对应的简化阶梯型矩阵。 若存在形如 0 = 1的方程,则方程组无解。

int a[100], n, T, ans;

int main() {
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        for (int i = 1, j; i <= n; i++) {
            scanf("%d", &j);
            a[i] ^= j;
            a[i] |= 1 << i;
        }
        int x, y;
        while (scanf("%d%d", &x, &y) && x && y) {
            a[y] |= 1 << x;
        }
        ans = 1;
        for (int i = 1; i <= n; i++) {
            for (int j = i + 1; j <= n; j++)  if (a[j] > a[i]) swap(a[i], a[j]);
            if (!a[i]) {
                ans = 1 << (n - i + 1);
                break;
            }
            if (a[i] == 1) {
                ans = 0;
                break;
            }
            for (int k = n; k; k--) {
                if (a[i] >> k & 1) {
                    for (int j = 1; j <= n; j++) if (i != j && (a[j] >> k & 1)) a[j] ^= a[i];
                    break;
                }
            }
        }
        if (ans == 0) puts("Oh,it's impossible~!!");
        else printf("%d\n", ans);
    }
}

 

posted @ 2020-07-17 09:07  MQFLLY  阅读(117)  评论(0编辑  收藏  举报