EXTENDED LIGHTS OUT POJ - 1222

原题链接

考察:高斯消元or递推+枚举

写过这种基本一样的题的题解= = ,看了大佬博客还能用高斯消元写,虽然是入门题但这操作我属实没想到= =

思路:

       如果要用高斯消元写,首先我们需要构造系数矩阵.较容易想到解就是按灯的次数.那么系数就是按这个灯对当前灯是否有效.等式右边是原灯状态.因为按灯效果要与原来相同,这样异或后就是0.所以需要构造30个方程.共31列.

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 const int N = 35;
 7 int xx[5] = {-1,1,0,0,0},yy[5] = {0,0,-1,1,0};
 8 bool a[N][N],b[N][N];
 9 void inits()
10 {
11     memset(a,0,sizeof a);
12     for(int i=1;i<=30;i++) scanf("%d",&a[i][31]);
13     for(int i=1;i<=5;i++)
14       for(int j=1;j<=6;j++)
15          for(int k=0;k<5;k++)
16          {
17              int dx = i+xx[k],dy = j+yy[k]; 
18              if(dx>0&&dx<=5&&dy>0&&dy<=6)//将控制该灯的系数赋值为1 
19                  a[(i-1)*6+j][(dx-1)*6+dy] = 1;
20          }
21 }
22 void Gauss()
23 {
24     int r,c;
25     for(r=1,c=1;c<=30;c++)
26     {
27         int t = r;
28         for(int i=r;i<=30;i++)
29           if(a[i][c])
30           {
31                t = i;
32                break;
33           }
34         if(!a[t][c]) continue;
35         for(int i=c;i<=31;i++) swap(a[t][i],a[r][i]);
36         for(int i=r+1;i<=30;i++)
37             if(a[i][c])
38                 for(int j=c;j<=31;j++) a[i][j]^=a[r][j];
39         r++;
40     }
41     for(int i=30;i>0;i--)
42        for(int j=i+1;j<=30;j++)
43           a[i][31]^= a[i][j]&a[j][31];
44 }
45 int main()
46 {
47     int T,kcase = 0;
48     scanf("%d",&T);
49     while(T--)
50     {
51         printf("PUZZLE #%d\n",++kcase);
52         inits();
53         Gauss();
54         for(int i=1;i<=30;i++)
55         {
56             printf("%d",a[i][31]);
57             if(i%6==0) printf("\n");
58             else printf(" ");
59         }
60     }
61     return 0;
62 } 

 

posted @ 2021-01-29 10:39  acmloser  阅读(48)  评论(0编辑  收藏  举报