这道题也是高斯消元解异或方程组,但是书上写的程序是有问题的。

用这个数据可以hack掉:

1

3

0 0 0

1 1 1

1 2

2 1

2 3

0 0

列出矩阵:

1 1 0 1

1 1 1 1

0 0 1 1

然后就会给出无解。实际上是有2解的。


下面来看正解:

异或方程组不能往上回消,也不能像书上那样每次把上下都消了。

直接消成上三角矩阵。

答案就是 (1 << 自由元个数)

关于无解的判定:自由元常数项和前面不统一时即无解。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 const int N = 35;
 5 
 6 int a[N], n;
 7 
 8 inline int Gauss() {
 9     int ans = 0;
10     for(int i = 1; i <= n; i++) {
11         for(int j = i; j <= n; j++) {
12             if(a[j] & (1 << i)) {
13                 std::swap(a[i], a[j]);
14                 break;
15             }
16         }
17         if(!((a[i] >> i) & 1)) {
18             if((a[i] > 1) ^ (a[i] & 1)) {
19                 return -1;
20             }
21             else {
22                 ans++;
23                 continue;
24             }
25         }
26         for(int j = i + 1; j <= n; j++) {
27             if(a[j] & (1 << i)) {
28                 a[j] ^= a[i];
29             }
30         }
31     }
32     return ans;
33 }
34 
35 inline void solve() {
36     scanf("%d", &n);
37     int c, b;
38     for(int i = 1; i <= n; i++) {
39         scanf("%d", &a[i]);
40     }
41     for(int i = 1; i <= n; i++) {
42         scanf("%d", &b);
43         a[i] ^= b;
44     }
45     while(scanf("%d%d", &c, &b)) {
46         if(!c) {
47             break;
48         }
49         a[b] |= (1 << c);
50     }
51     for(int i = 1; i <= n; i++) {
52         a[i] |= (1 << i);
53     }
54 
55     int t = Gauss();
56     if(t == -1) {
57         printf("Oh,it's impossible~!!\n");
58         return;
59     }
60     printf("%d\n", 1 << t);
61     return;
62 }
63 
64 int main() {
65     int T;
66     scanf("%d", &T);
67     while(T--) {
68         solve();
69         if(T) {
70             memset(a, 0, sizeof(a));
71         }
72     }
73     return 0;
74 }
AC代码

相关文章:

  • 2022-12-23
  • 2021-06-03
  • 2021-08-15
  • 2021-08-13
  • 2021-11-15
猜你喜欢
  • 2018-07-03
  • 2021-10-31
  • 2021-09-28
  • 2022-12-23
  • 2022-01-09
  • 2022-12-23
相关资源
相似解决方案