题意:1表示开着,0表示关着。当对某个等打开或关闭时,周围四个灯的状态也会改变,让输出一种开关灯的方式。
搞法1:高斯消元,不过感觉数据应该有问题,我解方程是按一定会存在唯一一组解的情况写的。
#include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #include <bitset> #include <queue> #include <stack> #include <string> #include <iostream> #include <cmath> #include <climits> typedef long long LL; using namespace std; int dx[4] = { -1, 0, 1, 0 }; int dy[4] = { 0, -1, 0, 1 }; int a[100][100]; void gao(int pos, int x, int y) { a[pos][x * 6 + y] = 1; for (int i = 0; i < 4; i++){ int xx = x + dx[i]; int yy = y + dy[i]; if (xx >= 0 && xx < 5 && yy >= 0 && yy < 6){ a[pos][xx * 6 + yy] = 1; } } } void Gauss(int equ, int var) { int k; int col; for (k = 0, col = 0; k < equ&&col < var; k++, col++){ int kk = k; for (int i = k + 1; i < equ; i++){ if (a[i][col]>a[kk][col]) kk = i; } if (kk != k){ for (int j = k; j <= var; j++) swap(a[k][j], a[kk][j]); } if (a[k][col] == 0){ k--; continue; } for (int i = 0; i < equ; i++){ if(i==k) continue; if (a[i][col]){ for (int j = col; j <= var; j++){ a[i][j] ^= a[k][j]; } } } } for (int i = 0; i<30; i++){ printf("%d ", a[i][30]); if ((i + 1) % 6 == 0) printf(" "); } } int m[30][30]; int main() { int T; cin >> T; int Icase = 0; while (T--){ memset(a, 0, sizeof(a)); printf("PUZZLE #%d ", ++Icase); for (int i = 0; i < 5; i++){ for (int j = 0; j < 6; j++){ scanf("%d", &m[i][j]); a[i * 6 + j][30] = m[i][j]; } } for (int i = 0; i < 5; i++){ for (int j = 0; j < 6; j++){ gao(i * 6 + j, i, j); } } Gauss(30, 30); } return 0; }
搞法2:枚举第一行状态,也就(1<<6)种,下面的开关状态也就确定了。
#include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #include <bitset> #include <queue> #include <stack> #include <string> #include <iostream> #include <cmath> #include <climits> typedef long long LL; using namespace std; int dx[4] = { 0, 1, 0, -1 }; int dy[4] = { 1, 0, -1, 0 }; int m[10][10]; int m1[10][10]; int ans[10]; void nong(int x, int y) { m1[x][y] ^= 1; for (int i = 0; i < 4; i++){ int xx = x + dx[i]; int yy = y + dy[i]; if (xx >= 0 && xx < 5 && yy >= 0 && yy < 6) m1[xx][yy] ^= 1; } } int gao(int x) { memset(ans, 0, sizeof(ans)); ans[0] = x; for (int i = 0; i < 5;i++) for (int j = 0; j < 6; j++) m1[i][j] = m[i][j]; for (int i = 0; i < 6; i++){ if (x&(1 << i)){ nong(0, i); } } for (int i = 1; i < 5; i++){ for (int j = 0; j < 6; j++){ if (m1[i - 1][j]){ ans[i] |= (1 << j); nong(i, j); } } } int flag = 1; for (int i = 0; i < 5&&flag; i++){ for (int j = 0; j < 6&&flag; j++) if (m1[i][j]) flag = 0; } return flag; } int main() { int T; cin >> T; int Icase = 0; while (T--){ printf("PUZZLE #%d ", ++Icase); for (int i = 0; i < 5;i++) for (int j = 0; j < 6; j++) scanf("%d", &m[i][j]); for (int i = 0; i < (1 << 6); i++){ int k = gao(i); if (k){ for (int j = 0; j < 5; j++){ for (int k = 0; k < 6; k++){ if (ans[j] & (1 << k)) printf("1 "); else printf("0 "); } cout << endl; } break; } } } return 0; }