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 }