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