P2040 打开所有的灯
题目背景
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个整数,表示最少打开所有灯所需要的步数。
输入输出样例
说明
这个题水不水,就看你怎么考虑了。。。。
思维好题???
好题。。。
正如题目所说。。。水不水就看怎么考虑了。
首先输入完成后判断一下是不是全都为1,此时直接输出0就好了,也省去了往后麻烦的操作。
dfs里面的变量是操作次数,为什么取9呢?。。。
怎么解释呢。。。一个一个来,,9次也算很多了。。
所以超过9次,,就返回上一步再来吧。
然后我们正常操作,把是0的点和其周围四个点变成和原来不一样的,
我这里是写的a[i][j]=!a[i][j],就是0,1取反,也可以用1减去a[i][j],得到的也是0,1取反.
然后每操作一次,就判断一下,是不是全都为1了。
然后如果还有点为0,那我们就继续操作,操作数+1,继续搜索、。。
其实这是一个模拟的过程,就看你的模拟思路好不好了。。
这个还比较好理解,代码:
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; int ans=2333; int a[4][4]; int xx[]={-1,0,0,1},yy[]={0,-1,1,0}; bool judge() { for(int i=1;i<=3;++i) for(int j=1;j<=3;++j) if(!a[i][j]) return 0; return 1; } void dfs(int x) { if(x>9) return ; for(int i=1;i<=3;++i) for(int j=1;j<=3;++j) if(!a[i][j]) { a[i][j]=1; for(int k=0;k<4;++k) { int dx=i+xx[k],dy=j+yy[k]; a[dx][dy]=!a[dx][dy]; } if(judge()) ans=min(ans,x); dfs(x+1); a[i][j]=0; for(int k=0;k<4;++k) { int dx=i+xx[k],dy=j+yy[k]; a[dx][dy]=!a[dx][dy]; } } } int main() { for(int i=1;i<=3;++i) for(int j=1;j<=3;++j) scanf("%d",&a[i][j]); if(judge()) { printf("0"); return 0; } dfs(1); printf("%d",ans); return 0; }
如果你不开心,那我就把右边这个帅傻子分享给你吧,
你看,他这么好看,那么深情的望着你,你还伤心吗?
真的!这照片盯上他五秒钟就想笑了。
一切都会过去的。