POJ - 1222: EXTENDED LIGHTS OUT (开关问题-高斯消元)
pro:给定5*6的灯的状态,如果我们按下一个灯的开关,它和周围4个都会改变状态。求一种合法状态,使得终状态全为关闭;
sol:模2意义下的高斯消元。 终于自己手打了一个初级板子。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; int a[40][40],ans[40]; int x[5]={0,0,0,1,-1}; int y[5]={0,1,-1,0,0}; void Guass() { rep(i,0,29){ int mark=i; rep(j,i+1,29) if(abs(a[j][i])>abs(a[mark][i])) mark=j; if(mark!=i) rep(j,0,30) swap(a[i][j],a[mark][j]); if(!a[i][i]) continue; //全为0 rep(j,i+1,29){ if(!a[j][i]) continue; //前面几排为0的不操作 rep(k,i,30){ a[j][k]^=a[i][k]; //a[j][k]=(a[j][k]&a[i][i])^(a[i][k]&a[j][i]); } } } for(int i=29;i>=0;i--){ if(!a[i][i]) continue; ans[i]=a[i][30]&a[i][i]; rep(j,0,i-1) a[j][30]^=(a[j][i]&ans[i]); } } int main() { int T,N,M,Ca=0; scanf("%d",&T); while(T--){ memset(a,0,sizeof(a)); rep(i,0,29) scanf("%d",&a[i][30]); rep(i,0,4) rep(j,0,5) { int t=i*6+j; rep(k,0,4) { if(i+x[k]>=0&&i+x[k]<=4&&j+y[k]>=0&&j+y[k]<=5){ a[(i+x[k])*6+j+y[k]][t]=1; } } } Guass(); printf("PUZZLE #%d\n",++Ca); rep(i,0,29) { printf("%d",ans[i]); if(i%6==5) putchar('\n'); else putchar(' '); } } return 0; }
It is your time to fight!