题目链接:AcWing 95. 费解的开关 - AcWing
题意: 有5 排 5列一共25盏灯,每盏灯有开和关两种状态, 初始灯开与关的状态不确定。现在可以对每盏灯进行操作,改变这盏灯的状态,同时这盏灯上下左右的灯的状态也会随之发生改变。问是否有一个最少的操作次数,而且该操作次数不能大于6,使所有的灯都变为开的状态。
分析: 可以想到的是对于每盏灯最多就操作一次,而且操作的顺序毫无影响。那么假设当前排已经操作完了,但是还有灭的灯,只能在下一排的同一个位置把他打开,所以一旦第一排要操作哪几个灯已经确定,剩下的排的操作都是固定的。因此第一排操作的状态一共有2^5种,只需要枚举这些状态,找出答案的最小值即可。
代码:
#include<bits/stdc++.h>
#define map unordered_map
#define all(a) a.begin(), a.end()
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, int> PLI;
const int N = 310 + 10;
const int mod = 99824353;
int n;
string s[5];
string ss[5];
int dx[5] = {-1, 0, 1, 0, 0}, dy[5] = {0, 1, 0, -1, 0};
void turn(int tx, int ty){
for(int i = 0; i < 5; i ++){
int x = tx + dx[i], y = ty + dy[i];
if(x < 0 || x >= 5 || y < 0 || y >= 5) continue;
if(ss[x][y] == '1') ss[x][y] = '0';
else ss[x][y] = '1';
}
}
void solve(){
cin>>n;
while(n --){
for(int i = 0; i < 5; i ++) cin>>s[i];
int ans = 7;
for(int i = 0; i < 32; i ++){
int step = 0;
for(int j = 0; j < 5; j ++) ss[j] = s[j];
for(int j = 0; j < 5; j ++){
if((i >> j) & 1){
turn(0, j);
step ++;
}
}
for(int j = 1; j < 5; j ++){
for(int k = 0; k < 5; k ++){
if(ss[j - 1][k] == '0') {
turn(j, k);
step ++;
}
}
}
bool f = 0;
for(int j = 0; j < 5; j ++){
if(ss[4][j] == '0') f = 1;
}
if(f) continue;
ans = min(ans, step);
}
if(ans > 6) ans = -1;
cout<<ans<<endl;
}
}
int main(){
cin.tie(0) -> sync_with_stdio(false);
//int t; cin>>t; while(t --)
solve();
}