Question link: http://poj.org/problem? Id = 1222
A matrix of 5x6 is composed of 0 and 1. If you perform an operation at one of the positions (I, j), the operation is performed at four locations. (Note: the so-called operation is to set the status 0-> 1 or 1-> 0)
This game has been used by average people since childhood. Finally, I will ask you which ones you need to select to transfer from the current status to the target status (all 0.
My approach is Gaussian (just learning ).
It is easy to write the I-th equation: A [I] ^ A [k1] ^ A [k2] ^ A [K3] ^ A [K4] = cur [I] ^ aim [I] (K1 ~ 4 indicates the number of the top, bottom, and left sides of the I.) A [x] indicates whether the X is 1 or 0.
The common Gaussian deyuan equation is addition, subtraction, multiplication, and division, but here it is an exclusive or relation.
However, you can still Delete the element. You only need to modify the Gaussian elimination process slightly.
Two points:
1) when J (j> I) is eliminated using line I, if a [J] [I] is 0, this line will not be deleted. In addition, if a [I] [I] is 0, this line cannot be used. just continue.
This is because the elimination method here is that the equation of line I and line J overlays a [I] [I] ^ A [J] [I] ^ A [I] [I + 1] ^ A [J] [I + 1]... = A [I] [N] ^ A [J] [N]
2) In The Back-to-generation process, only a [I] [N] ^ = (a [J] [N] & A [I] [J]) is required. you can understand the usage and relationship here.
Code:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdlib> 5 6 using namespace std; 7 const int N = 6*6; 8 typedef bool Mat[N][N+1]; 9 const int dir[4][2] = {1, 0, 0, 1, 0, -1, -1, 0};10 int cur[N][N], aim[N][N];11 12 void Guss(Mat &A, int n) {13 for (int i = 0; i < n; i++) {14 int r = i;15 for (int j = i + 1; j < n; j++) {16 if (abs(A[j][i]) > abs(A[r][i])) r = j;17 }18 if (r != i) for (int j = 0; j <= n; j++) swap(A[r][j], A[i][j]);19 for (int j = i + 1; j < n; j++) {20 if (!A[j][i]) continue;21 for (int k = i + 1; k <= n; k++) {22 A[j][k] ^= A[i][k];23 }24 }25 }26 for (int i = n-1; i >= 0; i--) {27 for (int j = i + 1; j < n; j++) {28 A[i][n] ^= (A[j][n]&&A[i][j]);29 }30 }31 }32 int n = 5, m = 6;33 int change(int x, int y) {34 return m * (x-1) + y - 1;35 }36 void solve() {37 Mat A;38 for (int i = 0; i < n*m; i++) for (int j = 0; j <= n*m; j++) A[i][j] = 0;39 40 for (int i = 1; i <= n; i++) {41 for (int j = 1; j <= m; j++) {42 int c = change(i, j);43 for (int k = 0; k < 4; k++) {44 int x = i + dir[k][0];45 int y = j + dir[k][1];46 if (x <= 0 || x > n || y <= 0 || y > m) continue;47 A[c][change(x, y)] = 1;48 }49 A[c][c] = 1;50 A[c][n*m] = cur[i][j] ^ aim[i][j];51 }52 }53 Guss(A, n*m);54 for (int i = 0; i < n*m; i++) {55 printf("%d", A[i][n*m]);56 if (i%6 == 5) puts("");57 else printf(" ");58 }59 }60 61 int main() {62 for (int i = 1; i <= n; i++) {63 for (int j = 1; j <= m; j++) {64 aim[i][j] = 0;65 }66 }67 int T; scanf("%d", &T);68 for (int cas = 1; cas <= T; cas++) {69 for (int i = 1; i <= n; i++) {70 for (int j = 1; j <= m; j++) {71 scanf("%d", &cur[i][j]);72 }73 }74 printf("PUZZLE #%d\n", cas);75 solve();76 }77 return 0;78 }
View code