poj1830(高斯消元解mod2方程组)

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

 

题意:中文题诶~

 

思路:高斯消元解 mod2 方程组

有 n 个变元,根据给出的条件列 n 个方程组,初始状态和终止状态不同的位置对应的方程右边常数项为1,状态相同的位置对于的方程组右边的常数项为0.然后用高斯消元解一下即可.若有唯一解输出1即可,要是存在 k 个变元,则答案为 1 << k, 因为每个变元都有01两种选择嘛~

 

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 #include <string.h>
 5 using namespace std;
 6 
 7 const int inf = 1e9;
 8 const int MAXN = 3e2;
 9 int equ, var;//有equ个方程,var个变元,增广矩正行数为equ,列数为var+1,从0开始计数
10 int a[MAXN][MAXN];//增广矩正
11 int free_x[MAXN];//用来存储自由变元(多解枚举自由变元可以使用)
12 int free_num;//自由变元个数
13 int x[MAXN];//解集
14 
15 int Gauss(void){//返回-1表示无解,0表示有唯一解,否则返回自由变元个数
16     int max_r, col, k;
17     free_num = 0;
18     for(k = 0, col = 0; k < equ && col < var; k++, col++){
19         max_r = k;
20         for(int i = k + 1; i < equ; i++){
21             if(abs(a[i][col] > abs(a[max_r][col]))) max_r = i;
22         }
23         if(a[max_r][col] == 0){
24             k--;
25             free_x[free_num++] = col;//这个是变元
26             continue;
27         }
28         if(max_r != k){
29             for(int j = col; j < var + 1; j++){
30                 swap(a[k][j], a[max_r][j]);
31             }
32         }
33         for(int i = k + 1; i < equ; i++){
34             if(a[i][col] != 0){
35                 for(int j = col; j < var + 1; j++){
36                     a[i][j] ^= a[k][j];
37                 }
38             }
39         }
40     }
41     for(int i = k; i < equ; i++){
42         if(a[i][col] != 0) return -1;//无解
43     }
44     if(k < var) return var - k;//返回自由变元个数
45     for(int i = var - 1; i >= 0; i--){
46         x[i] = a[i][var];
47         for(int j = i + 1; j < var; j++){
48             x[i] ^= (a[i][j] && x[j]);
49         }
50     }
51     return 0;
52 }
53 
54 void solve(void){
55     int op = Gauss();
56     if(op == -1) cout << "Oh,it's impossible~!!" << endl;//无解
57     else if(op == 0) cout << 1 << endl;
58     else cout << (1 << op) << endl;
59 }
60 
61 int y[30], z[30];
62 
63 int main(void){
64     int t, n;
65     string s;
66     cin >> t;
67     while(t--){
68         cin >> n;
69         equ = var = n;
70         for(int i = 0; i < n; i++){
71             cin >> y[i];
72         }
73         for(int i = 0; i < n; i++){
74             cin >> z[i];
75         }
76         for(int i = 0; i < n; i++){
77             a[i][n] = (y[i] != z[i]);
78             a[i][i] = 1;
79             x[i] = 0;
80         }
81         int cnt1, cnt2;
82         while(cin >> cnt1 >> cnt2 && cnt1 && cnt2){
83             a[--cnt2][--cnt1] = 1;
84         }
85         solve();
86         memset(a, 0, sizeof(a));
87     }
88     return 0;
89 }
View Code

 

posted @ 2017-09-24 22:13  geloutingyu  阅读(190)  评论(0编辑  收藏  举报