POJ 1222-EXTENDED LIGHTS OUT解题报告

链接:http://poj.org/problem?id=1222

这题是说有5*6个开关,0处于关闭状态,1处于开启状态,每按一个开关,周围的上下左右方向的开关会跟着翻转,而且题目中给了提示,任何一个开关,按偶数次和不按的作用是一样的,所以每个开关最多转换一次,问的是如何转换能达到全部都为关闭状态。我们可以知道,任意一个位置的开关由自己和周围的开关共同决定,那么可以对每一个开关建立一个方程,这样就有30个方程,30个未知数,一定有解,利用高斯消元加位运算可以解出每个未知数。

View Code
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define N 30
 5 using namespace std;
 6 int a[N][N];
 7 int x[N];
 8 int n;
 9 int Abs(int a)
10 {
11     return a<0?-a:a;
12 }
13 void guass()
14 {
15     int i,j,k,row;
16     n=30;
17     for(k=0;k<n;k++)//一次缩减矩阵的阶数
18     {
19         for(i=k;i<n;i++)//对每一个未知数找到第一个本列是1的方程
20         if(a[i][k]==1)
21         {
22             row=i;
23             break;
24         }
25         if(row!=k)//交换原来的列和第一个本列是1的方程,构成行阶梯型原始状态
26         {
27             for(j=k;j<n;j++)
28             {
29                 swap(a[i][j],a[k][j]);
30             }
31             swap(x[i],x[k]);
32         }
33         for(i=k+1;i<n;i++)//行阶梯型的化简
34         {
35             if(a[i][k]==0)
36             continue;
37             for(j=k+1;j<n;j++)
38             a[i][j]^=a[k][j];
39             x[i]^=x[k];
40         }
41     }
42     x[n-1]/=a[n-1][n-1];
43     for(i=n-2;i>=0;i--)//求解过程
44     {
45         for(j=i+1;j<n;j++)
46         x[i]^=(x[j]*a[i][j]);
47         x[i]/=a[i][i];
48     }
49 }
50 void init()//方程未知数的系数
51 {
52     int i,j,t1,t2,t3,t4;
53     for(i=0;i<30;i++)
54     {
55         t1=i/6;
56         t2=i%6;
57         for(j=0;j<30;j++)
58         {
59             t3=j/6;
60             t4=j%6;
61             if(Abs(t3-t1)+Abs(t4-t2)<=1)
62             a[i][j]=1;
63             else
64             a[i][j]=0;
65         }
66     }
67 }
68 int main()
69 {
70     int t,i,j,k;
71     scanf("%d",&t);
72     for(k=1;k<=t;k++)
73     {
74         for(i=0;i<30;i++)
75         scanf("%d",&x[i]);
76         init();
77         guass();
78         printf("PUZZLE #%d\n",k);
79         for(i=0;i<5;i++)
80         {
81             for(j=0;j<6;j++)
82             {
83                 if(j)
84                 printf(" ");
85                 printf("%d",x[i*6+j]);
86             }
87             printf("\n");
88         }
89     }
90     return 0;
91 }

 

posted @ 2012-09-05 11:52  zhenhai  阅读(199)  评论(0编辑  收藏  举报