• 费解的开关【DFS】【模拟】


    题目大意:

    给出n5×5的开关,按下一个开关会影响周围4个灯和自己(开变成关,关变成开)。求最少需要按多少次开关才能使得全部灯变亮?(6次以上则视为无法点亮)。


    思路:

    这道题如果用普通的广搜会T。。。
    这道题的正解如下:
    假设我们不动第一行的开关,那么如果要改变第一行的灯的状态,那么就只能更改第二行的位于该灯下面的那个开关来改变。例如:
    这里写图片描述
    如果我们固定了第一行,那么为了将全部都变成绿色,就必须利用第二行。例如,(1,1)是红色,为了让它变成绿色,就必须更改(2,1)。为了让(1,4)变成绿色,就必须更改(2,4)
    更改后图形如下:
    这里写图片描述
    那么我们再固定第二行,利用第三行来更改它(就像用第一行来更改第二行一样),就变成了
    这里写图片描述
    同理,更改第三行
    这里写图片描述
    再更改第四行
    这里写图片描述
    这是我们发现,最后还有一个灯是关着的,所以,这说明第一行的灯如果是这样的情况就无法成立
    那么就枚举第一行的点击方式,再继续按照刚才的方法,判断能否点玩即可。


    代码:

    #include <cstdio>
    #include <iostream>
    #define Inf 1e7
    using namespace std;
    
    int n,a[6][6],b[6][6],ans;
    
    int check(int x)  //判断当第一行的情况是否成立
    {
        int sum=x;
        for (int i=1;i<=5;i++)
         for (int j=1;j<=5;j++)
          b[i][j]=a[i][j];
        for (int i=1;i<=4;i++)
         for (int j=1;j<=5;j++)
          if (!b[i][j])  //第i行是关灯
          {
             sum++;  //记录次数
             b[i][j]=1-b[i][j];
             b[i+1][j]=1-b[i+1][j];
             b[i+1][j-1]=1-b[i+1][j-1];
             b[i+1][j+1]=1-b[i+1][j+1];
             b[i+2][j]=1-b[i+2][j];
          }
        for (int i=1;i<=5;i++)
         if (!b[5][i]) return Inf;  //判断最后一行是否全开
        return sum;
    }
    
    void dfs(int x,int k)  //枚举第一行的情况
    {
        if (x>5)  //第一行更改完毕
        {
            ans=min(ans,check(k));
            return;
        }
        a[1][x]=1-a[1][x];
        a[1][x-1]=1-a[1][x-1];
        a[1][x+1]=1-a[1][x+1];
        a[2][x]=1-a[2][x];
        dfs(x+1,k+1);  //按这个开关
        a[1][x]=1-a[1][x];
        a[1][x-1]=1-a[1][x-1];
        a[1][x+1]=1-a[1][x+1];
        a[2][x]=1-a[2][x];
        dfs(x+1,k);  //不按这个开关
        return;
    }
    
    int main()
    {
        scanf("%d",&n);
        while (n--)
        {
            for (int i=1;i<=5;i++)
             for (int j=1;j<=5;j++)
              scanf("%1d",&a[i][j]);
            ans=Inf;
            dfs(1,0);
            if (ans<7) printf("%d\n",ans);
             else printf("-1\n");
        }
        return 0;
    }
  • 相关阅读:
    linux常用命令的英文单词缩写
    Linux常用指令总结
    java exception "file not found or file not exist"
    Linux清空屏幕和清空当前输入的快捷键
    巨蟒python全栈开发-第10天 函数进阶
    为什么不能在函数中给全局变量赋值?
    巨蟒python全栈开发-第9天 初识函数
    巨蟒python全栈开发-第8天 文件操作
    windows10怎样关闭,开机启动项中不需要的应用?
    巨蟒python全栈开发-第7天 基本数据类型补充&深浅拷贝
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998783.html
Copyright © 2020-2023  润新知