Topic link: https: //vjudge.net/problem/POJ-1222
The meaning of problems: Given a matrix of 01 5 × 6, which includes its own vertically and horizontally inverted state will change when the state of a point, because there is no equivalent to twice flip flip, then each point or not inverted, or flipped once, ultimately seeking to overturn what can make the all-zero matrix.
Ideas:
Practice 1 (enumeration): because of the small data, can enumerate all possible first row, a total of six kinds << 1, each row after row in accordance with the decision, and this is determined by determining whether the last row of the condition proposal is feasible.
2 approach (Gaussian elimination): To say clearly is now assumed that the matrix of 2 × 3, such as now is to achieve a target state:
Now the state of the lamp in claim 6, the equivalent of six variables. Further six equations, respectively six points final state.
For example, 0 for the first lamp, it is able to affect the second 0,1,3 lamp, so it is the equation: (1 * x0) ^ (1 * x1) ^ (0 * x2) ^ (1 * x3) ^ (0 * x4) ^ (0 * x5) = 0, (0 state of the right side of the equation represents the beginning 0 lamps).
Similarly Equation 1 is the lamp of: (1 * x0) ^ (1 * x1) ^ (1 * x2) ^ (0 * x3) ^ (1 * x4) ^ (0 * x5) = 1.
Equation 6 can be listed, and then solved using Gaussian elimination, XOR and general equations of linear equations is the same.
For topic is 5 × 6 = 30 equations, respectively 30 shows a state variable of the lamp 30.
AC Code:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> using namespace std; const int maxn=40; int T,cas,a[maxn][maxn],ans[maxn]; void init(){ memset(a,0,sizeof(a)); memset(ans,0,sizeof(ans)); for(int i=0;i<5;++i){ for(int j=0;j<6;++j){ int t=i*6+j; a[t][t]=1; if(i>0) a[t][t-6]=1; if(i<4) a[t][t+6]=1; if(j>0) a[t][t-1]=1; if(j<5) a[t][t+1]=1; } } } void Gauss(int equ,int var){ int r=0,c=0; for(;r<equ&&c<var;++r,++c){ int Maxr=r; for(int i=r+1;i<equ;++i) if(abs(a[i][c])>abs(a[Maxr][c])) Maxr=i; if(a[Maxr][c]==0){ --r; continue; } if(Maxr!=r){ for(int i=c;i<=var;++i) swap(a[r][i],a[Maxr][i]); } for(int i=r+1;i<equ;++i){ if(a[i][c]==0) continue; for(int j=c;j<=var;++j) a[i][j]^=a[r][j]; } } for(int i=var-1;i>=0;--i){ ans[i]=a[i][var]; for(int j=i+1;j<equ;++j) ans[i]^=(a[i][j]&ans[j]); } } int main(){ scanf("%d",&T); while(T--){ init(); for(int i=0;i<30;++i) scanf("%d",&a[i][30]); Gauss(30,30); printf("PUZZLE #%d\n",++cas); for(int i=0;i<5;++i){ for(int j=0;j<6;++j){ printf("%d",ans[i*6+j]); if(j!=5) printf(" "); } printf("\n"); } } return 0; }