NOIP 考前 高斯消元练习

Posted on 2016-11-06 17:29  yyjxx2010xyu  阅读(191)  评论(0编辑  收藏  举报

POJ 1830

列出n个方程右边为最后的情况

每一行代表第几个灯的情况,每一行代表是否按第几个按钮写出方程即可。

 1 #include <cstdio>
 2 #include <cstring>
 3 const int Maxn=100;
 4 int M[Maxn][Maxn],Ans,a[Maxn],b[Maxn],p,q,KASE,n;
 5 inline void Swap(int &x,int &y) {int t=x;x=y;y=t;}
 6 inline bool Check(int x)
 7 {
 8     for (int i=1;i<=n;i++) if (M[x][i]) return false;
 9     return true;
10 }
11 bool Gauss()
12 {
13     int Pos=1;
14     for (int i=1;i<=n;i++)
15     {
16         int k=0;
17         for (int j=Pos;j<=n;j++) if (M[j][i]) {k=j; break;}
18         if (k==0) continue;
19         for (int j=1;j<=n+1;j++) Swap(M[Pos][j],M[k][j]);
20         for (int j=1;j<=n;j++)
21             if (M[j][i] && j!=Pos)
22                 for (int l=1;l<=n+1;l++) M[j][l]^=M[Pos][l];
23         Pos++;
24     }
25     int cnt=0;
26     for (int i=1;i<=n;i++)
27         if (Check(i))
28         {
29             if (M[i][n+1]) return false;
30             cnt++;
31         }
32     return Ans=(1<<cnt);
33 }
34 int main()
35 {
36     scanf("%d",&KASE);
37     for (int Kase=1;Kase<=KASE;Kase++)
38     {
39         scanf("%d",&n);
40         memset(M,0,sizeof(M));
41         for (int i=1;i<=n;i++) scanf("%d",&a[i]);
42         for (int i=1;i<=n;i++) scanf("%d",&b[i]);
43         for (int i=1;i<=n;i++) M[i][n+1]=a[i]^b[i];
44         for (int i=1;i<=n;i++) M[i][i]=1;
45         while (scanf("%d%d",&p,&q)!=EOF)
46         {
47             if (p==0 && q==0) break;
48             M[q][p]=1;
49         }
50         if (Gauss()) printf("%d\n",Ans); else puts("Oh,it's impossible~!!");
51     }
52     return 0;
53 }
POJ 1830