#include <cstdio> #include <cstring> #include <algorithm> const int maxn = 30; int inp[maxn + 5][maxn + 5], kase, T; void gauss() { for (int i = 0; i < maxn; i++) { int k = i; while (k < maxn && !inp[k][i])k++; for (int j = 0; j <= maxn; j++) std::swap(inp[i][j], inp[k][j]); for (int j = 0; j < maxn; j++) if (i != j && inp[j][i]) for (int p = 0; p <= maxn; p++) inp[j][p] = inp[i][p] ^ inp[j][p]; } } int main(int argc, char const *argv[]) { scanf("%d", &T); while (T--) { memset(inp, 0, sizeof(inp)); for (int i = 0; i < maxn; i++) scanf("%d", &inp[i][maxn]), inp[i][i] = 1; for (int i = 0; i < maxn; i++) { if (i % 6 != 0) inp[i - 1][i] = 1; if (i % 6 != 5) inp[i + 1][i] = 1; if (i > 5) inp[i - 6][i] = 1; if (i < 24) inp[i + 6][i] = 1; } gauss(); printf("PUZZLE #%d\n", ++kase); for (int i = 0; i < maxn; i++) printf("%d%c", inp[i][maxn], i % 6 == 5 ? '\n' : ' '); } return 0; }
楼上为简洁版,楼下为套用模板的版本。
#include <cstdio> #include <cstring> #include <algorithm> const int maxn = 30; int inp[maxn + 5][maxn + 5], kase, T; // void gauss() // { // for (int i = 0; i < maxn; i++) // { // int k = i; // while (k < maxn && !inp[k][i])k++; // for (int j = 0; j <= maxn; j++) // std::swap(inp[i][j], inp[k][j]); // for (int j = 0; j < maxn; j++) // if (i != j && inp[j][i]) // for (int p = 0; p <= maxn; p++) // inp[j][p] = inp[i][p] ^ inp[j][p]; // } // } int equ, var, x[maxn], free_num, free_x[maxn]; int gauss() { int max_r, col, k; free_num = 0; for (k = 0, col = 0; k < equ && col < var; k++, col++) { max_r = k; for (int i = k + 1; i < equ; i++) if (abs(inp[i][col]) > abs(inp[max_r][col])) max_r = i; if (inp[max_r][col] == 0) { k--; free_x[free_num++] = col; continue; } if (max_r != k) for (int j = col; j < var + 1; j++) std::swap(inp[k][j], inp[max_r][j]); for (int i = k + 1; i < equ; i++) if (inp[i][col] != 0) for (int j = col; j < var + 1; j++) inp[i][j] ^= inp[k][j]; } for (int i = k; i < equ; i++) if (inp[i][col] != 0) return -1; if (k < var) return var - k; for (int i = var - 1; i >= 0; i--) { x[i] = inp[i][var]; for (int j = i + 1; j < var; j++) x[i] ^= (inp[i][j] && x[j]); } return 0; } int main(int argc, char const *argv[]) { scanf("%d", &T); while (T--) { memset(inp, 0, sizeof(inp)); for (int i = 0; i < maxn; i++) scanf("%d", &inp[i][maxn]), inp[i][i] = 1; for (int i = 0; i < maxn; i++) { if (i % 6 != 0) inp[i - 1][i] = 1; if (i % 6 != 5) inp[i + 1][i] = 1; if (i > 5) inp[i - 6][i] = 1; if (i < 24) inp[i + 6][i] = 1; } equ = 30, var = 30; gauss(); printf("PUZZLE #%d\n", ++kase); for (int i = 0; i < maxn; i++) printf("%d%c", x[i], i % 6 == 5 ? '\n' : ' '); } return 0; }
当press作用于inp上时,效果就是对应位模2加(异或),那么每一个点作为一个未知数,他的上下左右的值会决定他的值。