费解的开关 switches

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了费解的开关 switches相关的知识,希望对你有一定的参考价值。

【题目描述】:

你玩过“拉灯”游戏吗?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”。

 

 

【样例输入】

【样例输出】

3

00111

01011

10001

11010

11100

 

11101

11101

11110

11111

11111

 

01111

11111

11111

11111

11111

3

2

-1

【数据范围及描述】:

对于30%的数据,n<=5

对于100%的数据,n<=500

 

这题目确实很费解,我一开始想到用meet in the middle + hash 判同

代码又丑又长

听了某位大神说只需枚举第一行的状态,然后就可以贪心了

今后优化搜索时,我们一定要从题目状态之间的关系or 特点来思考!

 

技术分享
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn=6;
 8 int N;
 9 int ans;
10 
11 struct node
12 {
13     int g[maxn][maxn];
14 };
15 
16 void dfs(int c,node &now,int sum)
17 {
18     if(c==6) 
19     {
20         for(int i=2;i<=5;i++)
21         {
22             for(int j=1;j<=5;j++)
23             {
24                 if(now.g[i-1][j]==0) 
25                 {
26                     now.g[i-1][j]=1;
27                     if(j!=1)now.g[i][j-1]=1-now.g[i][j-1];
28                     if(j!=5)now.g[i][j+1]=1-now.g[i][j+1];
29                     if(i!=5)now.g[i+1][j]=1-now.g[i+1][j];
30                     now.g[i][j]=1-now.g[i][j];
31                     sum++;
32                 }
33             }
34         }
35         bool flag=true;
36         for(int j=1;j<=5;j++)
37             if(now.g[5][j]==0) flag=false;
38         if(flag) ans=min(ans,sum);
39         return ;
40     }
41     {
42         node *p=new node;
43         *p=now;
44         dfs(c+1,*p,sum);
45         delete p;
46     }
47     {
48         node *p=new node;
49         *p=now;
50         p->g[1][c]=1-p->g[1][c];
51         if(c!=1) p->g[1][c-1]=1-p->g[1][c-1];
52         if(c!=5) p->g[1][c+1]=1-p->g[1][c+1];
53         p->g[2][c]=1-p->g[2][c];
54         dfs(c+1,*p,sum+1);
55         delete p;
56     }
57 }
58     
59 
60 int main()
61 {
62     scanf("%d\\n",&N);
63     while(N--)
64     {
65         node root;
66         char S[6][6];
67         for(int i=1;i<=5;i++)
68         {
69             scanf("%s\\n",S[i]+1);
70             for(int j=1;j<=5;j++)
71                 root.g[i][j]=S[i][j]-0;
72         }
73         scanf("\\n");
74         ans=7;
75         dfs(1,root,0);
76         if(ans<=6) cout<<ans<<endl;
77         else cout<<-1<<endl;
78     }
79     return 0;
80 }
81         
View Code

技术分享

 

以上是关于费解的开关 switches的主要内容,如果未能解决你的问题,请参考以下文章

AcWing 95 费解的开关

费解的开关

题解AcWing95费解的开关

[VIJOS1197] 费解的开关

费解的开关

费解的开关