洛谷P2040 打开所有的灯 题解 状态压缩枚举
题目链接:https://www.luogu.com.cn/problem/P2040
这道题目是一道比较简单的题目,可以用枚举或者DP做,我这里是用二进制遍历所有的状态,枚举所有的等开或者不开的情况,最后求出代码的。实现代码如下:
#include <bits/stdc++.h>
using namespace std;
int a[3][3], ans = INT_MAX;
int dir[5][2] = { 0, 0, -1, 0, 1, 0, 0, -1, 0, 1 };
void rev(int x, int y) {
for (int i = 0; i < 5; i ++) {
int xx = x + dir[i][0], yy = y + dir[i][1];
if (xx >= 0 && xx < 3 && yy >= 0 && yy < 3) a[xx][yy] = !a[xx][yy];
}
}
bool check() {
for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) if (!a[i][j]) return false;
return true;
}
void rev_all(int st) {
for (int i = 0; i < 9; i ++) if (st & (1<<i)) rev(i/3, i%3);
if (check()) ans = min(ans, __builtin_popcount(st));
for (int i = 0; i < 9; i ++) if (st & (1<<i)) rev(i/3, i%3);
}
int main() {
for (int i = 0; i < 3; i ++) for (int j = 0; j < 3; j ++) cin >> a[i][j];
for (int st = 0; st < (1<<9); st ++)
rev_all(st);
cout << ans << endl;
return 0;
}