P10449 费解的开关
费解的开关
题目描述
你玩过“拉灯”游戏吗?
每一个灯都有一个开关,游戏者可以改变它的状态。
每一步,游戏者可以改变某一个灯的状态。
游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。
我们用数字
下面这种状态
10111 01101 10111 10000 11011
在改变了最左上角的灯的状态后将变成:
01111 11101 10111 10000 11011
再改变它正中间的灯后状态将变成:
01111 11001 11001 10100 11011
给定一些游戏的初始状态,编写程序判断游戏者是否可能在
输入格式
第一行输入正整数
以下若干行数据分为
每组数据描述了一个游戏的初始状态。
各组数据间用一个空行分隔。
输出格式
一共输出
对于某一个游戏初始状态,若 -1
。
样例 #1
样例输入 #1
3 00111 01011 10001 11010 11100 11101 11101 11110 11111 11111 01111 11111 11111 11111 11111
样例输出 #1
3 2 -1
提示
测试数据满足
思路
对于一行中的0,我们不难想到,直接点击它会影响左右的数字。所以便去点击这个0对应下一行的位置。
还有一个性质,当第一行的点击方式固定了之后,按照上述的方法点击剩下的
于是我们不妨考虑枚举第一行的点击方式,采用位运算枚举的方式,有
最后记得另用数组暂存原矩阵。
代码实现
#include<bits/stdc++.h> using namespace std; char a[6][6],b[6][6]; int dx[5]={1,-1,0,0,0}; int dy[5]={0,0,0,-1,1},ans=1e9; //void print() //{ // for(int i=0;i<5;i++) // { // cout<<a[i]<<endl; // } //} bool check(int x,int y) { return x>=0&&x<5&&y>=0&&y<5; } void change(int i,int j) { for(int p=0;p<5;p++) { int x=i+dx[p],y=j+dy[p]; if(check(x,y)) a[x][y]^=1; } } int main() { ios::sync_with_stdio(false); int t; cin>>t; while(t--) { for(int i=0;i<5;i++) { cin>>a[i]; } int cnt=0; for(int pos=0;pos<32;pos++) { cnt=0; memcpy(b,a,sizeof a); for(int i=0;i<5;i++) { if(pos>>i&1) { cnt++; change(0,i); } } for(int i=0;i<4;i++) { for(int j=0;j<5;j++) { if(a[i][j]=='0') { cnt++; change(i+1,j); } } } bool flag=true; for(int i=0;i<5;i++) { if(a[4][i]=='0') { flag=false; break; } } if(flag) ans=min(ans,cnt); memcpy(a,b,sizeof b); } if(ans>6) { ans=-1; } cout<<ans<<endl; ans=1e9; } return 0; }
在首次写完代码后,结果是WA
,后来经过多次调试才知道memcpy
函数这种浅复制不能复制string
这种数据结构,还有含指针的结构体也不能复制。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话