zoukankan      html  css  js  c++  java
  • HDU 3364 高斯消元

    Lanterns

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 2396    Accepted Submission(s): 937


    Problem Description
    Alice has received a beautiful present from Bob. The present contains n lanterns and m switches. Each switch controls some lanterns and pushing the switch will change the state of all lanterns it controls from off to on or from on to off. A lantern may be controlled by many switches. At the beginning, all the lanterns are off. 

    Alice wants to change the state of the lanterns to some specific configurations and she knows that pushing a switch more than once is pointless. Help Alice to find out the number of ways she can achieve the goal. Two ways are different if and only if the sets (including the empty set) of the switches been pushed are different.
     
    Input
    The first line contains an integer T (T<=5) indicating the number of test cases.
    The first line of each test case contains an integer n (1<=n<=50) and m (1<=m<=50).
    Then m lines follow. Each line contains an integer k (k<=n) indicating the number of lanterns this switch controls.
    Then k integers follow between 1 and n inclusive indicating the lantern controlled by this switch.
    The next line contains an integer Q (1<=Q<=1000) represent the number of queries of this test case.
    Q lines follows. Each line contains n integers and the i-th integer indicating that the state (1 for on and 0 for off) of the i-th lantern of this query.
     
    Output
    For each test case, print the case number in the first line. Then output one line containing the answer for each query.
    Please follow the format of the sample output.
     
    Sample Input
    2 3 2 2 1 2 2 1 3 2 0 1 1 1 1 1 3 3 0 0 0 2 0 0 0 1 0 0
     
    Sample Output
    Case 1: 1 0 Case 2: 8 0
     
    Source

     题意:

    就是给了 n 个灯 m 个开关,每个开关能够控制很多灯,当然了每个灯也可以由多种开关控制。现在给了你每个开关能够控制的灯的标号,

    然后给你一个最终状态,让你求的是能够达到这个最终状态的方法数(初始状态都是关着的,开着是 1,关着是 0).

    思路:

    解题思路:

    有 n 个灯也就意味着我们要列 n 个方程, m 个开关就是 m 个未知数,首先通过输入的开关控制的灯可以确定初始的 a(系数矩阵),注意的是 a 矩阵的列和行的变化。

    然后通过给定的最终状态来确定 a∗x = b 的 列矩阵 b,然后就正常高消就行了,还有需要注意的一点是:它给定的 Q 个询问的时候,我们要提前将 a 矩阵保存

    因为高消之后 a 矩阵就变了,所以我们就将 a 矩阵保存。

     代码:

      1 //#include"bits/stdc++.h"
      2 #include<sstream>
      3 #include<iomanip>
      4 #include"cstdio"
      5 #include"map"
      6 #include"set"
      7 #include"cmath"
      8 #include"queue"
      9 #include"vector"
     10 #include"string"
     11 #include"cstring"
     12 #include"time.h"
     13 #include"iostream"
     14 #include"stdlib.h"
     15 #include"algorithm"
     16 #define db double
     17 #define ll long long
     18 #define vec vector<ll>
     19 #define mt  vector<vec>
     20 #define ci(x) scanf("%d",&x)
     21 #define cd(x) scanf("%lf",&x)
     22 #define cl(x) scanf("%lld",&x)
     23 #define pi(x) printf("%d
    ",x)
     24 #define pd(x) printf("%f
    ",x)
     25 #define pl(x) printf("%lld
    ",x)
     26 //#define rep(i, x, y) for(int i=x;i<=y;i++)
     27 #define rep(i, n) for(int i=0;i<n;i++)
     28 const int N   = 1e2+ 5;
     29 //const int mod = 1e9 + 7;
     30 //const int MOD = mod - 1;
     31 const int inf = 0x3f3f3f3f;
     32 const db  PI  = acos(-1.0);
     33 const db  eps = 1e-10;
     34 using namespace std;
     35 int equ,var;//equ个方程,var个变量,增广矩阵行数为equ,列数为var+1,分别为0到var
     36 int a[N][N];//增广矩阵
     37 int x[N];//存储自由变元
     38 int f_x[N];
     39 int free_x;//自由变元个数
     40 void swap(int &x,int &y){
     41     int t;
     42     t=x,x=y,y=t;
     43 }
     44 int Gauss()
     45 {
     46     int ma_r,col,k;
     47     free_x=0;
     48     for(k=0,col=0;k<equ&&col<var;k++,col++){
     49         ma_r = k;
     50         for (int i = k + 1; i < equ; i++) if (abs(a[i][col] > abs(a[ma_r][col]))) ma_r = i;//取系数最大的一行
     51         if (!a[ma_r][col]) {
     52             k--;
     53             f_x[free_x++] = col;
     54             continue;
     55         }
     56         if (ma_r != k)
     57             for (int j = col; j < var + 1; j++) swap(a[k][j], a[ma_r][j]);//与当前行交换
     58 
     59         for (int i = k + 1; i < equ; i++)
     60             if (a[i][col] != 0)
     61                 for (int j = col; j < var + 1; j++) a[i][j] ^= a[k][j];//消除其他行第col列的变量
     62     }
     63     for(int i=k;i<equ;i++) if(a[i][col]!=0) return -1;//没被消除则无解
     64 
     65     if(k<var) return var-k;//自由变元个数
     66     //唯一解,回代
     67     for(int i=var-1;i>=0;i--){
     68         x[i]=a[i][var];
     69         for(int j=i+1;j<var;j++) x[i]^=(a[i][j]&&x[j]);//自下而上
     70     }
     71     return 0;
     72 }
     73 int b[N][N];
     74 int n,m;
     75 int main()
     76 {
     77     int t;
     78     ci(t);
     79     for(int I=1;I<=t;I++)
     80     {
     81         ci(n),ci(m);
     82         memset(a,0, sizeof(a));
     83         for(int i=0;i<m;i++){
     84             int k,c;
     85             ci(k);
     86             for(int j=0;j<k;j++) ci(c),a[c-1][i]=1;
     87         }
     88         equ=n,var=m;
     89         for(int i=0;i<equ;i++){
     90             for(int j=0;j<var;j++){
     91                 b[i][j]=a[i][j];
     92             }
     93         }
     94         int q;
     95         ci(q);
     96         printf("Case %d:
    ",I);
     97         while(q--)
     98         {
     99             for(int i=0;i<equ;i++)
    100                 for(int j=0;j<var;j++)
    101                     a[i][j]=b[i][j];
    102             for(int i=0;i<n;i++) ci(a[i][var]);
    103             int ans=Gauss();
    104             if(ans==-1) puts("0");
    105             else pl(1ll<<ans);
    106         }
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    构造函数析构函数为什么没有返回值?
    std::tr1::shared_ptr 使用的一点体会
    C++完美实现Singleton模式
    为什么C++中空类和空结构体大小为1?
    同时判断CPU是大端还是小端完全实现
    优先级反转
    linux sed 批量替换字符串
    禁掉Apache web server签名 How to turn off server signature on Apache web server
    Python中用format函数格式化字符串的用法
    Eclipse (indigo) 中安装jdk包并运行Maven
  • 原文地址:https://www.cnblogs.com/mj-liylho/p/8911244.html
Copyright © 2011-2022 走看看