费解的开关
是否在6步之内让所有的灯都开着
假设第一行固定,那么通过第二行修改第一行,之后,通过第三行修改第二行(如果第二行为0,在第三行上按一下,变为1)
所以只要枚举第一行的状态即可
时间复杂度 25
*500 * 20
第一行的可能 * 测试样例组数 * 递推数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; int n; char g[10][10]; int dp[5][2] = {{0,0},{0,1},{0,-1},{1,0},{-1,0}}; void handle(int x,int y){ for(int i = 0; i < 5; i++){ int dx = x + dp[i][0],dy = y + dp[i][1]; if(dx >= 0 && dx < 5 && dy >= 0 && dy < 5){ g[dx][dy] ^= 1; } } } int work(){ int ans = 1000000; for(int i = 0; i < 1 << 5; i++){//枚举所有状态 char backup[10][10]; memcpy(backup,g, sizeof g);//先复制一遍 int res = 0; for(int j = 0; j < 5; j++){ if(i >> j & 1){//如果是1的话,按下去变为0 res++; handle(0,j); } } for(int k = 0; k < 4; k++){ for(int j = 0; j < 5; j++){ if(g[k][j] == '0'){ res++; handle(k + 1,j); } } } bool flag = true; for(int j = 0; j < 5; j++) if(g[4][j] == '0') { flag = false; break; } if(flag) ans = min(ans,res); memcpy(g, backup,sizeof(g)); } if(ans > 6) return -1; return ans; } int main(){ //freopen("in","r",stdin); ios::sync_with_stdio(0); cin >> n; while(n--){ for(int i = 0; i < 5; i++) cin >> g[i]; cout << work() << endl; } return 0; }