[Acwing 95] puzzled switch – enumeration + search

(The title is from ACwing)

Have you played the “pull the light” game? The 25 lights are arranged in a 5×5 square. Each light has a switch, and the player can change its state. At each step, the player can change the state of a certain light. The player changing the state of a light will have a chain reaction: the lights adjacent to the light up, down, left, and right will also change their states accordingly.

We use the number “1” to indicate an on light, and the number “0” to indicate an off light.

Given the initial state of some games, write a program to determine whether the player can turn on all the lights within 6 steps.

Input format

Enter a positive integer in the first linen

“>n< /span>, which means there are n

“> nThe initial state of the game to be solved.

The following rows of data are divided into n“>n groups, each group of data has 5 rows and each row has 5 characters. Each set of data describes the initial state of a game. Each group of data is separated by a blank line.

Output format

Total output n

“>n< /span> line data, each line has an integer less than or equal to 6, which means that it takes at least a few steps for the corresponding game state in the input data to enable all lights Brighten.

For a certain initial state of the game, if all the lights cannot be turned on within 6 steps, “-1” will be output.

The essence of the question is: to solve the minimum number of steps required to transform a 5 * 5 01 square matrix into a square matrix composed of only 1 through the above operation. If you simply enumerate the changed points every time to search, the size of the state space cannot be tolerated, which obviously does not work.

   Actually, the transformation given in the question has two very important properties. First, each point is transformed at most once, because repeated operations are invalid; second, different sequences of the same operations will not affect the final result, because the cumulative effect at each position is the same.

  From these two points, we found that we can enumerate some transformations to recursively all operations. Specifically, consider performing the transformation line by line, then the transformation performed by all lines above the current line i has been determined; if there is 0 at the kth position on the i-1th line, then only by changing the i-th line The k-th position makes the i-1th line legal, which is the key to solving this problem. Therefore, we can enumerate the 2^5 = 32 transformations performed in the first row in binary, and then recursively recursive operations on the second to fifth rows. Finally, check whether the fifth line is all 1s, and if the fifth line is valid, update the answer with the current number of steps.

  The lesson learned from this question is to use the statement “ios::sync_with_stdio(0)” with caution, because this instruction cancels the compatibility of cin and C standard input and output. Once the hand slides, use cin at the same time. And getchar, scanf and other C library read functions will cause errors. It is best to consider the application of this sentence when you read the string, and you should usually read it by hand to avoid tragedy.

Code:

  1. #include< /span>
  2. #include
  3. #include< iostream>
  4. #include
  5. #include
  6. usingnamespacestd;
  7. constint inf= 0x3f3f3f3f;
  8. int sw[10][10], tmp[10][10], cnt, ans;
  9. int addx[5 ] = {0, 0, 0, -1, 1}, addy[5] = {0, 1, -1, 0, 0};
  10. void change(int x, int y, int a[10][10]) {< /span>
  11. int tx, ty;
  12. for (int i= 0; i< 5; ++i) {
  13. tx = x + addx[i], ty = y + addy[i];
  14. < li>if(a[tx][ty]==-1)continue;

  15. a[tx][ty] = !a[tx][ty];
  16. } ++cnt;
  17. < li>}

  18. void init(int x){
  19. memcpy(tmp, sw, sizeof(tmp));
  20. for(< span class="datatypes">int i = 1; i<= 5; ++i)
  21. if(x>>( i- 1)& 1)
  22. change(1, i, tmp);
  23. int main(){
  24. int T;
  25. cin>> T;
  26. while(T- -){
  27. Ans = inf;
  28. memset(sw, -1, sizeof(sw)) ;
  29. char ch;
  30. for (< span class="datatypes">int i = 1; i <= 5; ++i) {
  31. while(!isdigit( ch))
  32. ch = getchar();
  33. for( int j = 1; j <= 5; ++j)
  34. sw[i][j]= ch-48, ch= getchar( );
  35. /* for (int i = 1; i<= 5;++i) {< /span>
  36. for (int j = 1; j<= 5;++j)
  37. cout<< sw[i][j]<<"";
  38. cout<
  39. */
  40. for (int x= 0; x<32;++x){
  41. cnt = 0;
  42. init(x);
  43. < li class="alt">for(int i= 2;i<=5;++i)

  44. for(intj=1;j<=5;++j)
  45. if (!tmp[i- 1][j])
  46. Change(i, j,
  47. >

  48. for (int i= 1;i<= 5;++i)< /li>
  49. if (!tmp[5][i]) cnt=inf;
  50. = Min(ans, cnt);
  51. if (ans<= 6)
  52. Cout<< ans<
  53. else puts(“-1”);“-1”); /span>
  54. return 0;< /li>
  55. }

Leave a Comment

Your email address will not be published.