AcWing 95. 费解的开关 解题思路及代码

先贴个题目:

以及原题链接:

95. 费解的开关 - AcWing题库icon-default.png?t=N7T8https://www.acwing.com/problem/content/97/ 以及我的代码:

#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
char a[5][5];
char backup[5][5];
void turn(int x,int y){     //开关函数
    int n[5] = {-1, 0, 0, 0, 1}, m[5] = {0, 0, -1, 1, 0};   //偏移量
    for (int i = 0; i < 5;++i){     
        int xx = x + n[i], yy = y + m[i];
        if(xx<0||xx>4||yy<0||yy>4)  //防止数组越界
            continue;
        else{
            if(a[xx][yy]=='1')
                a[xx][yy] = '0';
            else
                a[xx][yy] = '1';
        }
    }
    return;
} 
int main()
{
    int T;
    cin >> T;
    for (int ii = 0;ii<T;++ii){
        int step = 0,Min = 7;
        for (int i = 0; i < 5; ++i)
            for (int j = 0; j < 5; ++j)
                cin >> a[i][j];
        memcpy(backup, a, sizeof(a));   //贮存原状态
        for (int i = 0; i < 32;++i){    //第一行枚举   
            step = 0;
            memcpy(a, backup, sizeof(a));
            for (int j = 0; j < 5;++j)
                if(i>>j&1){ 
                    turn(0, j);
                    step++;
                }
                    
            for (int j = 1; j < 5;++j)  
                for (int k = 0; k < 5;++k)
                    if (a[j - 1][k]=='0'){
                        turn(j, k);
                        step++;
                    }        
            int sign = 1;
            for (int i = 0; i < 5;++i)
                if(a[4][i]=='0'){
                    sign = 0;
                    break;
                }
            if(sign)
                Min = min(step, Min);   //取最小步数
        }
    if(Min>6)
        Min = -1;
    cout << Min<<endl;
    }
    return 0;
}

这题基本是用到了递推和枚举,阅读题目后最关键的解题思路在于发现了三个规律:1.每个灯的选择只有按1次或者不按2.每个灯按的顺序不影响最后结果3.一行状态定完只有下一行能改变,即第一行确定则第二行固定,第二行固定则第三行固定,所以只需要枚举第一行即可。然后在

for (int i = 0; i < 32;++i){

for (int j = 0; j < 5;++j)
                if(i>>j&1){ 
                    turn(0, j);
                    step++;
                }

这里,我利用二进制思想,将10进制0-31看作一行灯的开关状态,然后利用位运算来判断是否需要摁开关。然后因为1-4行必须灯全亮,只需在枚举最后判断最后一行是否灯全亮即可。

by————2024.1.29刷题记录

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值