2040 打开所有的灯

难度:普及/提高-

题目类型:搜索/枚举/模拟

提交次数:3

涉及知识: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即可。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int a[5][5];
 5 bool visited[5][5];
 6 int ans = 1000;
 7 void print(){
 8     int i, j;
 9     for(i = 1; i < 4; i++){
10         for(j = 1; j < 4; j++)
11             cout<<a[i][j]<<" ";
12         cout<<endl;
13     }
14 }//打印,用于调试 
15 bool finished(){
16     bool ans = true;
17     int i, j;
18     for(i = 1; i <= 3; i++)
19         for(j = 1; j <= 3; j++)
20             if(!a[i][j]) return false;
21     return true;
22 }//判断是否全亮 
23 void click(int x, int y){
24     a[x][y] = !a[x][y];
25     a[x-1][y] = !a[x-1][y];
26     a[x+1][y] = !a[x+1][y];
27     a[x][y+1] = !a[x][y+1];
28     a[x][y-1] = !a[x][y-1];
29 }//点击函数
30 void dfs(int step){
31     int i, j;
32     if(finished()){
33         if(ans>step) ans = step;
34         return;
35     }    
36     if(step>=9) return; //减枝
37     if(step>ans) return;
38     else{
39         for(i = 1; i <= 3; i++)
40             for(j = 1; j <= 3; j++)
41                 if(!visited[i][j]){
42                     click(i, j); 
43                     visited[i][j] = true;
44                     //cout<<step<<endl;
45                     //print();
46                     dfs(step+1);//注意++step会出错
47                     click(i, j); //取消=按回去 
48                     visited[i][j] = false;
49                 }     
50     } 
51 }
52 int main(){
53     int i, j;
54     for(i = 1; i <= 3; i++)
55         for(j = 1; j <= 3; j++)
56             cin>>a[i][j];    
57     dfs(0);//不是1
58     cout<<ans;
59     return 0;
60 }

备注:

这道题耗了我一天的时间!还要选课什么的,真是焦头烂额。一会儿我还要去做化学和物理……

问题挺多的。思路就是搜索。然而DFS从来没写对过,仿佛受了诅咒。老师说我思路乱,我发现其实是因为没有严格按DFS框架来。有一个问题,最优解里一个灯不可能按2次,我最开始居然没想明白!另外应该是dfs(0),想想就知道了。

应该是dfs(step+1)不要写++step!会出错!出错!出错!


被老师强迫着思考为什么++step会出错。

想明白了:

dfs(++step);拆成两行就是step = step+1;  dfs(step); 这样等dfs一圈回来,step已经不是原来的那个step了,物是人非。

 

posted @ 2016-08-25 19:35  timeaftertime  阅读(175)  评论(0编辑  收藏  举报