每日一题——费解的开关
题目
题解
将第一层的状态确定下来,第二层就能确定,同理到最后一层也就确定了,所以只需要枚举第一层所有状态就可以确定步数,满足条件就存下步数,比较并选取最小步数,最后如果步数大于6输出-1。对于翻转操作,dx、dy可以很方便得对周围方格进行枚举,别忘了每枚举完第一层一个状态需要恢复到题目所给的状态。memcpy就是复制操作,backup这个数组就是保存备份初始状态。
参考代码
#include<iostream>
#include<cstring>
using namespace std;
const int N = 10, INF = 0x3f3f3f3f;
int T;
int dx[]={0,-1,0,1,0};
int dy[]={0,0,1,0,-1};
char g[N][N],backup[N][N];
void turn(int x, int y){
for(int i = 0; i < 5; i ++){
int xx = x + dx[i], yy = y + dy[i];
if(xx >= 0 && xx <=4 && yy >= 0 && yy <=4) g[xx][yy] ^= 1;
}
}
int work(){
int res = INF;
memcpy(backup, g, sizeof g);
for(int k = 0; k < 1 << 5; k ++){
int temp = 0;
for(int j = 0; j < 5; j ++){
if((k >> j) & 1) turn(0, j),temp++;
}
for(int i = 0; i < 4; i ++){
for(int j = 0; j < 5; j++){
if(g[i][j] == '0') turn(i + 1, j),temp++;
}
}
bool is_flag = true;
for(int i = 0; i < 5; i ++)
if(g[4][i] == '0'){
is_flag = false;
break;
}
if(is_flag) res = min(res, temp);
memcpy(g,backup,sizeof g);
}
if(res > 6) res = -1;
return res;
}
int main(){
cin >> T;
while(T --){
for(int i = 0; i < 5; i ++) cin >> g[i];
cout << work() << endl;
}
return 0;
}

浙公网安备 33010602011771号