J - EXTENDED LIGHTS OUT
阿新 • • 發佈:2020-07-21
與這道題一樣,都是高斯消元求異或方程組。
一共\(30\)盞燈,每盞燈影響上下左右的燈,基本上就是矩陣改一下。
最後求解方程,自由元隨你定。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int n; int a[35],b[35]; int g[35][35]; long long ksm(long long x,int y){ long long z = 1; while(y){ if(y & 1) z = z * x; y >>= 1; x = x * x; } return z; } int ans[35]; int main(){ int T; scanf("%d",&T); for(int cas = 1; cas <= T; ++ cas){ memset(g,0,sizeof(g)); int n = 30; for(int i = 0; i < 5; ++ i) for(int j = 1; j <= 6; ++ j){ scanf("%d",&g[i * 6 + j][31]); } for(int i = 0; i < 5; ++ i) for(int j = 1; j <= 6; ++ j){ int id, ps = i * 6 + j; if(i > 0) id = (i - 1) * 6 + j, g[id][ps] = 1; if(i < 5) id = (i + 1) * 6 + j, g[id][ps] = 1; if(j > 1) id = i * 6 + j - 1, g[id][ps] = 1; if(j < 6) id = i * 6 + j + 1, g[id][ps] = 1; } for(int i = 1; i <= n; ++ i) g[i][i] = 1; int now = 1; for(int i = 1; i <= n; ++ i){ bool flag = 0; int pos = -1; for(int j = now; j <= n; ++ j){ if(g[j][i] == 1) { flag = 1; pos = j; break; } } if(!flag) continue; for(int j = 1; j <= n + 1; ++ j) swap(g[now][j],g[pos][j]); for(int j = now + 1; j <= n; ++ j){ if(g[j][i] == 0) continue; for(int k = 1; k <= n + 1; ++ k) g[j][k] ^= g[now][k]; } ++ now; } printf("PUZZLE #%d\n",cas); bool flag = 1; for(int i = now; i <= n; ++ i){ if(g[i][n + 1] != 0) { flag = 0; break; } } if(!flag) { puts("Oh,it's impossible~!!"); continue; } memset(ans,0,sizeof(ans)); for(int i = now - 1; i >= 1; -- i){ int pos = -1; for(int j = 1; j <= n; ++ j) if(g[i][j] != 0) { pos = j; break; } ans[pos] = g[i][n + 1]; for(int j = n; j > pos; -- j) ans[pos] ^= (ans[j] & g[i][j]); } for(int i = 0; i < 5; ++ i){ for(int j = 1; j <= 6; ++ j) printf("%d ",ans[i * 6 + j]); puts(""); } } return 0; }