洛谷 P2040 打开所有的灯-dfs
生活随笔
收集整理的這篇文章主要介紹了
洛谷 P2040 打开所有的灯-dfs
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目背景
pmshz在玩一個益(ruo)智(zhi)的小游戲,目的是打開九盞燈所有的燈,這樣的游戲難倒了pmshz。。。
題目描述
這個燈很奇(fan)怪(ren),點一下就會將這個燈和其周圍四盞燈的開關狀態全部改變。現在你的任務就是就是告訴pmshz要全部打開這些燈。
例如
0 1 1
1 0 0
1 0 1
點一下最中間的燈【2,2】就變成了
0 0 1
0 1 1
1 1 1
再點一下左上角的燈【1,1】就變成了
1 1 1
1 1 1
1 1 1
達成目標。最少需要2步。
輸出2即可。
輸入格式
九個數字,3*3的格式輸入,每兩個數字中間只有一個空格,表示燈初始的開關狀態。(0表示關,1表示開)
輸出格式
1個整數,表示最少打開所有燈所需要的步數。
輸入輸出樣例
輸入
0 1 1
1 0 0
1 0 1
輸出
2
代碼如下:
#include <iostream> using namespace std; const int N = 5; int g[N][N]; int ans = 10; void turn(int x,int y)//開關燈 {g[x][y] = 1-g[x][y];g[x-1][y] = 1-g[x-1][y];g[x+1][y] = 1-g[x+1][y];g[x][y+1] = 1-g[x][y+1];g[x][y-1] = 1-g[x][y-1]; }void dfs(int n) {if (n > ans) return ;//剪枝,不剪枝會超時//超過最小的次數就返回,初始次數為10,規律:它總共步驟不會超過9次int sum = 0;for (int i = 1;i<=3;i++)for (int j = 1;j<=3;j++)sum+=g[i][j];if (sum==9) ans = min(ans,n-1);//加起來等于9,就是燈全部亮的情況for (int i = 1;i<=3;i++)for (int j = 1;j<=3;j++){turn(i,j);dfs(n+1);turn(i,j);} }int main() {for (int i = 1;i<=3;i++)for (int j = 1;j<=3;j++)cin>>g[i][j];dfs(1);cout<<ans<<endl;return 0; }增加一個標記數組,剪枝。
代碼如下:
#include <iostream> using namespace std; const int N = 5; int g[N][N]; int ans = 10; bool vis[N][N];void turn(int x, int y) { //開關燈g[x][y] = 1 - g[x][y];g[x - 1][y] = 1 - g[x - 1][y];g[x + 1][y] = 1 - g[x + 1][y];g[x][y + 1] = 1 - g[x][y + 1];g[x][y - 1] = 1 - g[x][y - 1]; }void dfs(int n) {if (n > ans)return ;//剪枝,不剪枝會超時//超過最小的次數就返回,初始次數為10,規律:它總共步驟不會超過9次int sum = 0;for (int i = 1; i <= 3; i++)for (int j = 1; j <= 3; j++)sum += g[i][j];if (sum == 9)ans = min(ans, n - 1); //加起來等于9,就是燈全部亮的情況for (int i = 1; i <= 3; i++)for (int j = 1; j <= 3; j++) {if (!vis[i][j]) {vis[i][j] = true;turn(i, j);dfs(n + 1);vis[i][j] = false;turn(i, j);}} }int main() {for (int i = 1; i <= 3; i++)for (int j = 1; j <= 3; j++)cin >> g[i][j];dfs(1);cout << ans << endl;return 0; }總結
以上是生活随笔為你收集整理的洛谷 P2040 打开所有的灯-dfs的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 艾灸减肥一个月瘦多少
- 下一篇: 刮痧后多久可以吹空调