zoukankan      html  css  js  c++  java
  • [POJ1830]开关问题(高斯消元,异或方程组)

    题目链接:http://poj.org/problem?id=1830

    题意:中文题面,求的是方案数。

    首先可以知道, 如果方案数不止一个的话,说明矩阵行列式值为0,即存在自由变元,由于变量只有两种状态,那么方案数就是2^自由变元数。

    从起始状态到终止状态,只需要关心起始和终止哪些状态不一样就行,也就是翻转奇数次。

    由于是倒推,所以开关的影响要反过来存。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long LL;
     5 const int maxn = 33;
     6 int equ, var;
     7 int a[maxn][maxn];
     8 int x[maxn];
     9 int free_x[maxn];
    10 int free_num;
    11 
    12 int gauss() {
    13     int max_r, col, k;
    14     free_num = 0;
    15     for(k = 0, col = 0; k < equ && col < var; k++, col++) {
    16         max_r = k;
    17         for(int i = k + 1; i < equ; i++) {
    18             if(abs(a[i][col]) > abs(a[max_r][col]))
    19                 max_r = i;
    20         }
    21         if(a[max_r][col] == 0) {
    22             k--;
    23             free_x[free_num++] = col;
    24             continue;
    25         }
    26         if(max_r != k) {
    27             for(int j = col; j < var + 1; j++)
    28                 swap(a[k][j], a[max_r][j]);
    29         }
    30         for(int i = k + 1; i < equ; i++) {
    31             if(a[i][col] != 0) {
    32                 for(int j = col; j < var + 1; j++) {
    33                     a[i][j] ^= a[k][j];
    34                 }
    35             }
    36         }
    37     }
    38     for(int i = k; i < equ; i++) {
    39         if(a[i][col] != 0)
    40             return -1;
    41     }
    42     if(k < var) return var - k;
    43     for(int i = var - 1; i >= 0; i--) {
    44         x[i] = a[i][var];
    45         for(int j = i + 1; j < var; j++) {
    46             x[i] ^= (a[i][j] & x[j]);
    47         }
    48     }
    49     return 0;
    50 }
    51 
    52 int main() {
    53     // freopen("in", "r", stdin);
    54     int T, _ = 1;
    55     char wtf[66] = "Oh,it's impossible~!!";
    56     scanf("%d", &T);
    57     while(T--) {
    58         scanf("%d", &var);
    59         equ = var;
    60         memset(a, 0, sizeof(a));
    61         memset(x, 0, sizeof(x));
    62         memset(free_x, 0, sizeof(free_x));
    63         for(int i = 0; i < var; i++) {
    64             scanf("%d", &a[i][var]);
    65             a[i][i] = 1;
    66         }
    67         int u, v;
    68         for(int i = 0; i < var; i++) {
    69             scanf("%d", &u);
    70             a[i][var] ^= u;
    71         }
    72         while(~scanf("%d%d",&u,&v) && u+v) {
    73             a[v-1][u-1] = 1;
    74         }
    75         int ret = gauss();
    76         if(ret == -1) puts(wtf);
    77         else printf("%lld
    ", (LL)((LL)1 << ret));
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    Sass代码重用----Sass继承
    Sass代码重用
    Scss基本运算-------颜色运算
    Scss基本运算-------字符运算
    Scss基本运算-------数字运算
    7.Scss的基本运算
    6.Scss注释
    css横竖屏判断
    禁止页面缩放及meta便签常用属性
    微信小程序 错误记录
  • 原文地址:https://www.cnblogs.com/kirai/p/6138077.html
Copyright © 2011-2022 走看看