费解的开关

https://www.acwing.com/problem/content/97/

思路:
在上述规则的01矩阵的点击游戏中,很容易发现三个性质:
1.每个位置至多会被点击一次
2.若固定了第一行,则满足题意的点击方案至多只有一种。其原因是:当第i行某一位为1时,若前i行被固定,只等点击第i+1行该位置上的数字才能使第i行的这一位改变状态。
3.点击的先后顺序不影响最终结果。
对第一行的点击方案可以位运算,枚举00000~11111这32中情况,为1的位就是第一行被点击的位。

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include <queue>
using namespace std;

char a[10][10];
int b[10][10];
int c[10][10];
int n;
void click(int x,int y){
    b[x][y]^=1;
    b[x][y-1]^=1;
    b[x][y+1]^=1;
     b[x-1][y]^=1;
     b[x+1][y]^=1;
    return ;

}
bool check(){
    for(int i=1;i<=5;i++)
        for(int j=1;j<=5;j++)
            if(!b[i][j]) return false;
    return true;

}
int work(){
   int t=1e7;

    for(int i=1;i<=(1<<5);i++){
             int ans=0;
             memcpy(b,c,sizeof(c));
        for(int j=0;j<5;j++)
        if(i>>(j)&1) {
        click(1,j+1);
        ans++;
    }
    for(int j=1;j<=4;j++)
            for(int k=1;k<=5;k++)
    if(!b[j][k]){
        click(j+1,k);
        ans++;
    }
    if(check()){

        t=min(ans,t);

    }
    }
    return t;
}
int main()
{
    cin>>n;
    while (n--){
            memset(a,0,sizeof(a)) ;
        memset(b,0,sizeof(b)) ;
    for(int i=1;i<=5;i++){
        cin>>a[i];

    }
    for(int i=1;i<=5;i++)
        for(int j=1;j<=5;j++)
            c[i][j]=a[i][j-1]-'0';
            int anss=work();
    if(anss<=6) cout<<anss<<endl;
    else cout<<-1<<endl;

    }


 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

轩辕青山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值