AcWing 95. 费解的开关

95. 费解的开关 - AcWing题库

题目大意:给定5x5的矩阵,元素全为1或0,判断是否可以在6步以内将所有的0换成1(每改变一次,其相邻位置的元素也要改变)1->0,0->1,如果可以,输出最小步数,否则输出-1

解题思路:对于每1盏灯,其都可以有两种操作,一个是按,一个是不按,所以对于一行元素来说总共有2的5次方次操作,二进制表示范围为00000~11111,我们对第一行元素枚举所有情况,每次将为0的灯点亮,下一行位置就会变暗,我们每次都用下一行来改变上一行的状态(将0变为1),枚举到第五行的时候判断这个时候第五行有没有暗的灯,有则代表不可能将所有的灯变亮,否则则输出最少的步数。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N=6;//多开一个空间存放'\0'
char g[N][N],backup[N][N];
int dx[5]={-1,0,1,0,0},dy[5]={0,1,0,-1,0};
void turn(int x,int y)
{
	for(int i=0;i<5;i++)
	{
		int a=x+dx[i],b=y+dy[i];
		if(a<0||a>=5||b<0||b>=5) continue;
		g[a][b]^=1;//异或运算,'0'和'1'只有二进制只有最后不同,同则0,不同则1
	}
}
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		for(int i=0;i<5;i++) cin>>g[i];
		int res=10;
		for(int op=0;op<32;op++)
		{
			memcpy(backup,g,sizeof(g));//备份数组,后面要还原
			int step=0;
			for(int i=0;i<5;i++)
			{
				if(op>>i&1)//判断二进制的第i位为1,代表按下开关(人为规定)
				{
					step++;//每按一次步数+1
					turn(0,4-i);
				}
			}
			for(int i=0;i<4;i++)//i从0到4,最后一行特判
			{
				for(int j=0;j<5;j++)
				{
					if(g[i][j]=='0')
					{
						step++;
						turn(i+1,j);//用下一行来影响上一行的结果
					}
				}
			}
			bool dark=false;//对最后一行特判
			for(int i=0;i<5;i++)
			{
				if(g[4][i]=='0')
				{
					dark=true;
					break;
				}
			}
			if(dark==false) res=min(res,step);//32种方案中最小的那种
			memcpy(g,backup,sizeof(g));//恢复g数组
		}
		if(res>6) res=-1;
		cout<<res<<endl;
}
	return 0;
}

AcWing 95. 费解的开关 - AcWing

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值