其他分享
首页 > 其他分享> > AcWing 95. 费解的开关

AcWing 95. 费解的开关

作者:互联网

 

 

 

 

 

 我们可以通过枚举第一行的每一种状态,然后后一行的状态只能由前面一行确定,这样就可以找到对应的最小步数。

我的Acwing里的题解:

开始给我看懵了,一直不理解下面这行代码

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

y总视频里也是一笔带过,很多题解里面也是没有说明为什么 op >> i & 1 就开灯。
难道 !(op >> i & 1) 就不能开灯了? 我一直在纠结却一直没有用实际行动去证明。
最后看了好多题解之后,我忍无可忍,还是动手操作了一下,发现也是可以的。
我恍然大悟,其实op >> i & 1 可以说是一个规定,规定第i位是1的,就开灯,所以我也可以规定是0的就开灯。
难道不是吗? 很多题解都没有说明这一点,我不知道他们是否真的知道这行代码的含义,但是我开始真的不知道,所以我不可能含糊的过去。

#include <cstring>
#include <cstdio>
using namespace std;
char g[5][5], backup[5][5];
int dx[5] = {-1, 0, 1, 0, 0}, dy[5] = {0, 1, 0, -1, 0};
int n;

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 > 4 || b < 0 || b > 4) continue;
        backup[a][b] ^= 1;
    }
}
int main()
{
    scanf("%d", &n);

    while(n--)
    {
        for(int i = 0; i < 5; i++)
            scanf("%s", &g[i]);

        int ans = 7;

        for(int op = 0; op < 32; op++)
        {
            int cnt = 0;

            memcpy(backup, g, sizeof backup);

            for(int i = 0; i < 5; i++)
            {
                if(!(op >> i &1))
                {
                    turn(0, i);
                    cnt++;
                }
            }

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

            bool success = true;

            for(int i = 0; i < 5; i++)
                if(backup[4][i] == '0')
                    success = false;

            if(success && ans > cnt) ans = cnt;
        }

        if(ans > 6) ans = -1;

        printf("%d\n", ans);
    }

    return 0;
}

标签:cnt,int,backup,费解,++,ans,AcWing,95,op
来源: https://www.cnblogs.com/MoonSkyy/p/15942366.html