Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1882
A very good question.
Give N * m(1 <= n, m <= 16)Matrix, each grid has both black and white sides. When you flip a grid, it will flip up, down, left, and right. The last question is the minimum number of flip steps to make the grid completely white.
You only need to enumerate the status of the first row, because the flip of column J in the I (I> = 2) Row is restricted by the previous row, only when a row is 'x', the row J column can be flipped, making the I-1 row J column changed '. '; otherwise, column J of row I cannot be flipped. Proceed in sequence. When the last line is completely white, the flip is successful.
An important optimization: WHEN n <m, the matrix is transposed, so that the number of States changes from (1 <m)-1 to (1 <n)-1.
After running for 280 ms and reading other people's blogs, he should have flipped by line. I just don't understand some bitwise operations...
# Include <stdio. h> # include <string. h >#include <algorithm> # include <stack> # include <vector> # include <queue> # define ll long # DEFINE _ ll _ int64using namespace STD; const int INF = 0x3f3f3f; int n, m; char map [17] [17]; int sta [17], TMP [17]; int bit [17]; int ans; void CAL () {bit [0] = 1; for (INT I = 1; I <17; I ++) bit [I] = (bit [I-1] <1);} void input () {memset (STA, 0, sizeof (STA )); // record the status of each row if (n> = m) {for (int I = 0; I <n; I ++) {scanf ("% s", map [I]); For (Int J = 0; j <m; j ++) {If (Map [I] [J] = 'X') sta [I] = (STA [I] <1) + 1; else sta [I] <= 1 ;}}// optimized. When m <n, the matrix is converted to else {for (INT I = 0; I <N; I ++) {scanf ("% s", map [I]); For (Int J = 0; j <m; j ++) {If (Map [I] [J] = 'X') sta [J] = (STA [J] <1) + 1; else sta [J] <= 1 ;}} swap (n, m) ;}} void solve () {int step; ans = inf; For (INT I = 0; I <(1 <m); I ++) {memcpy (TMP, STA, sizeof (STA); ST Ep = 0; // first locate the column to be flipped in the first row and flip for (Int J = 0; j <M & step <ans; j ++) {If (bit [J] & I) {step ++; If (j> 0) TMP [0] ^ = bit [J-1]; If (j <s-1) TMP [0] ^ = bit [J + 1]; TMP [0] ^ = bit [J]; TMP [1] ^ = bit [J];} // flip row J for (Int J = 1; j <n & step <ans; j ++) {for (int K = 0; k <M & step <ans; k ++) {If (bit [k] & TMP [J-1]) {step ++; If (k> 0) TMP [J] ^ = bit [k-1]; If (m-1) TMP [J] ^ = bit [k + 1]; TMP [J] ^ = bit [k]; TMP [J + 1] ^ = bit [K] ;}}} If (! TMP [n-1]) ans = min (ANS, step) ;}} int main () {CAL (); While (~ Scanf ("% d", & N, & M) {If (n = 0 & M = 0) break; input (); solve (); if (ANS = inf) printf ("damaged billboard. \ n "); else printf (" You have to tap % d tiles. \ n ", ANS);} return 0 ;}