poj1222 EXTENDED LIGHTS OUT

【题意】

  一个5*6的矩阵,对一个位置操作可以使自己和相邻格子取反(0变1,1变0),给出开始状态,求一组操作的解使得全部为0.

【题解】

  模版题,对每个格子标号,建立方程组,直接高斯消元即可了。我也不明白为什么必有解。

【代码】

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 struct node
 6 {
 7     int vec[32],c;
 8 }a[32];
 9 int T,x,cnt,X[32],id[8][8];
10 void gauss()
11 {
12     for (int i=1;i<=30;++i)
13     {
14         for (int j=i;i<=30;++j)
15             if (a[j].vec[i])
16             {
17                 swap(a[i],a[j]);
18                 break;
19             }
20         for (int j=i+1;j<=30;++j)
21             if (a[j].vec[i])
22             {
23                 if (a[i].c)    a[j].c^=1;
24                 for (int k=i;k<=30;++k)
25                     if (a[i].vec[k])    a[j].vec[k]^=1;
26             }
27     }
28     for (int i=30;i;--i)
29     {
30         for (int j=i+1;j<=30;++j)
31             if (a[i].vec[j] && X[j])    a[i].c^=1;
32         X[i]=a[i].c;
33     }
34 }
35 int main()
36 {
37     scanf("%d",&T);
38     for (int i=1;i<=5;++i)
39         for (int j=1;j<=6;++j)
40             id[i][j]=++cnt;    
41     for (int Q=1;Q<=T;++Q)
42     {
43         memset(a,0,sizeof(a));
44         for (int i=1;i<=5;++i)
45             for (int j=1;j<=6;++j)
46                 scanf("%d",&a[id[i][j]].c);        
47         for (int i=1;i<=5;++i)
48             for (int j=1;j<=6;++j)
49             {
50                 x=id[i][j];
51                 if (i>1)    a[x].vec[id[i-1][j]]=1;
52                 if (i<5)    a[x].vec[id[i+1][j]]=1;
53                 if (j>1)    a[x].vec[id[i][j-1]]=1;
54                 if (j<6)    a[x].vec[id[i][j+1]]=1;
55                 a[x].vec[x]=1;
56             }
57         gauss();
58         printf("PUZZLE #%d\n",Q);
59         for (int i=1;i<=30;++i)
60             if (i%6)    printf("%d ",X[i]);
61             else    printf("%d\n",X[i]);
62     }
63     return 0;
64 }
View Code

 

posted @ 2017-09-24 14:13  Bleacher  阅读(93)  评论(0编辑  收藏