acw:费解的开关

acw:费解的开关

第一行灯的亮暗由第一行和第二行来决定,因此:假如第一行确定了,那么第二行就确定了,依次类推,第三行确定,第四行确定,第五行确定。
所以说只需要遍历第一行的情况即可,然后下面一行灯是否按动由上面一行灯的状态来决定。
首先由while来循环选择的矩阵,此时要输入要写在这个while里面下面的for外面,同时当前矩阵的最短步数也要写在while里面下面的for外面 ,然后由for来循环选择当前矩阵的第一行的32种情况,接下来要对当前矩阵进行操作,因此还需要创建一个傀儡矩阵来进行操作,当前矩阵作为模板,每次重新选择矩阵的第一行时,就对傀儡矩阵进行刷新。

第一行的灯状态的通过01来表示,0表示灯的状态不变,1表示灯的状态改变。
序列表示的是二进制数,for循环十进制数,然后通过>>来间接将其转换为二进制数,然后通过&来判断当前位置的值是1还是0。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 6;
char bk[N][N], st[N][N];
int n;
int dx[] = {1,0,-1,0,0}, dy[] = {0,1,0,-1,0};

//turn:改变包括这个灯在内的5个灯的状态
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 || b < 0 || b > 5 || a > 5 ) continue;
        st[a][b]^=1;
    }
}
int main()
{
    cin >> n;
    while(n--)
    {  
      
       int res = 10;
       for(int i = 0; i < 5 ; i ++ ) cin >> st[i];
       for(int op = 0; op < 32; op ++ )
       {
           memcpy(bk,st,sizeof st);
            int step = 0;
           for(int i = 0;i < 5; i ++ )
           {
               if(op >> i & 1)
               {
                   step ++ ;
                   turn(0,i);
               }
           }
           for(int i = 0; i < 4; i ++ )
             for(int j = 0; j < 5 ; j ++ )
             {
                 if(st[i][j] == '0')  
                 {
                     step ++ ;
                     turn(i+1,j);
                 }
             }
            bool it = false;
            
            for(int i = 0; i < 5; i ++ )
            {
                if(st[4][i]=='0')
                {
                    it = true;
                    break;
                }
            }
             if(!it)res = min(res,step);
              memcpy(st,bk,sizeof bk);
       }
       if(res > 6) cout << -1 << endl;
       else cout << res << endl;
      
    }
    return 0;
}

turn:改变包括这个灯在内的5个灯的状态

 for(int op = 0; op < 32; op ++ )
       {
           memcpy(bk,st,sizeof st);
            int step = 0;
           for(int i = 0;i < 5; i ++ )
           {
               if(op >> i & 1)
               {
                   step ++ ;
                   turn(0,i);
               }
           }

第一行的32种情况,
step表示步数,第二个for依次检查第一行每个灯(从后到前)的状态

for(int i = 0; i < 4; i ++ )
             for(int j = 0; j < 5 ; j ++ )
             {
                 if(st[i][j] == '0')  
                 {
                     step ++ ;
                     turn(i+1,j);
                 }
             }

对剩下四行进行操作,每一行的操作由上一行来决定

 bool it = false;
            
            for(int i = 0; i < 5; i ++ )
            {
                if(st[4][i]=='0')
                {
                    it = true;
                    break;
                }
            }
             if(!it)res = min(res,step);
              memcpy(st,bk,sizeof bk);
       }
       if(res > 6) cout << -1 << endl;
       else cout << res << endl;

整个操作完毕之后,要判断是否能将其全部化为1,同时step<6,然后按情况对result进行操作,

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值