ACWING 95 費解的開關 解題記錄

你玩過「拉燈」遊戲嗎?25盞燈排成一個5x5的方形。每個燈都有一個開關,遊戲者能夠改變它的狀態。每一步,遊戲者能夠改變某一個燈的狀態。遊戲者改變一個燈的狀態會產生連鎖反應:和這個燈上下左右相鄰的燈也要相應地改變其狀態。

咱們用數字「1」表示一盞開着的燈,用數字「0」表示關着的燈。下面這種狀態

10111
01101
10111
10000
11011
在改變了最左上角的燈的狀態後將變成:

01111
11101
10111
10000
11011
再改變它正中間的燈後狀態將變成:

01111
11001
11001
10100
11011
給定一些遊戲的初始狀態,編寫程序判斷遊戲者是否可能在6步之內使全部的燈都變亮。

輸入格式
第一行輸入正整數n,表明數據中共有n個待解決的遊戲初始狀態。

如下若干行數據分爲n組,每組數據有5行,每行5個字符。每組數據描述了一個遊戲的初始狀態。各組數據間用一個空行分隔。

輸出格式
一共輸出n行數據,每行有一個小於等於6的整數,它表示對於輸入數據中對應的遊戲狀態最少須要幾步才能使全部燈變亮。

對於某一個遊戲初始狀態,若6步之內沒法使全部燈變亮,則輸出「-1」。

數據範圍
0<n≤500
輸入樣例:
3
00111
01011
10001
11010
11100

11101
11101
11110
11111
11111

01111
11111
11111
11111
11111
輸出樣例:

3
2
-1

https://www.acwing.com/problem/content/97/ios

 1 #include <iostream>
 2 #include <cstring>
 3 
 4 using namespace std;
 5 
 6 const int INF = 100000;
 7 
 8 char g[10][10];
 9 int dx[5] = {0, -1, 0, 1, 0}, dy[5] = {0, 0, 1, 0, -1};
10 
11 void turn(int x, int y)
12 {
13     for (int i = 0; i < 5; i ++ )
14     {
15         int a = x + dx[i], b = y + dy[i];
16         if (a >= 0 && a < 5 && b >= 0 && b < 5)
17         {
18             g[a][b] = '0' + !(g[a][b] - '0');
19         }
20     }
21 }
22 
23 int work()
24 {
25     int ans = INF;
26     for (int k = 0; k < 1 << 5; k ++ )
27     {
28         int res = 0;
29         char backup[10][10];
30         memcpy(backup, g, sizeof g);
31 
32         for (int j = 0; j < 5; j ++ )
33         {
34             if (k >> j & 1)
35             {
36                 res ++ ;
37                 turn(0, j);
38             }
39         }
40 
41         for (int i = 0; i < 4; i ++ )
42             for (int j = 0; j < 5; j ++ )
43                 if (g[i][j] == '0')
44                 {
45                     res ++ ;
46                     turn(i + 1, j);
47                 }
48 
49         bool is_successful = true;
50         for (int j = 0; j < 5; j ++ )
51             if (g[4][j] == '0')
52             {
53                 is_successful = false;
54                 break;
55             }
56 
57         if (is_successful) ans = min(ans, res);
58 
59         memcpy(g, backup, sizeof g);
60     }
61 
62     if (ans > 6) return -1;
63     return ans;
64 }
65 
66 int main()
67 {
68     int T;
69     cin >> T;
70     while (T -- )
71     {
72         for (int i = 0; i < 5; i ++ ) cin >> g[i];
73         cout << work() << endl;
74     }
75     return 0;
76 }
View Code
相關文章
相關標籤/搜索