zoukankan      html  css  js  c++  java
  • 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了,物是人非。

  • 相关阅读:
    偏态分布的均值与中位数关系
    Leetcode 769. Max Chunks To Make Sorted
    【STL】max_element()函数
    [LeetCode] 1338. Reduce Array Size to The Half
    [LeetCode] 985. Sum of Even Numbers After Queries
    [LeetCode] 984. String Without AAA or BBB
    [LeetCode] 1405. Longest Happy String
    [LeetCode] 1646. Get Maximum in Generated Array
    [LeetCode] 926. Flip String to Monotone Increasing
    [LeetCode] 1658. Minimum Operations to Reduce X to Zero
  • 原文地址:https://www.cnblogs.com/fangziyuan/p/5808139.html
Copyright © 2011-2022 走看看