洛谷__P2040 打开所有的灯
题目背景
pmshz 在玩一个益 (ruo) 智 (zhi) 的小游戏,目的是打开九盏灯所有的灯,这样的游戏难倒了 pmshz……
题目描述
这个灯很奇 (fan) 怪 (ren),点一下就会将这个灯和其周围四盏灯的开关状态全部改变。现在你的任务就是就是告诉 pmshz 要全部打开这些灯。
例如
点一下最中间的灯 (2,2) 就变成了
再点一下左上角的灯 (1,1) 就变成了
达成目标。
最少需要 2 步。
输入格式
9 个数字,以 3×3 的格式输入,每两个数字中间只有一个空格,表示灯初始的开关状态。(0 表示关,1 表示开)
输出格式
一个整数,表示最少打开所有灯所需要的步数。
输入输出样例
输入 #1
0 1 1
1 0 0
1 0 1
输出 #1
2
思路:
同一个开关不会被同时使用两次。(用了两次就回去了)
剩下的就是暴力搜索了。。。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 5, mod = 998244353;
int e[N][N];
int dx[5] = {0, 1, 0, -1, 0};
int dy[5] = {0, 0, 1, 0, -1};
int res = inf;
bool check() {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (e[i][j] == 0) return false;
}
}
return true;
}
void dfs(int x, int y, int cnt) {
if (cnt >= res) return;//剪枝
if (check()) {
res = min(res, cnt);
return;
}
for (int i = x; i <= 3; i++) {
for (int j = (i == x ? y : 1); j <= 3; j++) {
for (int k = 0; k < 5; k++) {
int nx = i + dx[k];
int ny = j + dy[k];
e[nx][ny] ^= 1;
}
dfs(i, j + 1, cnt + 1);
for (int k = 0; k < 5; k++) {//复原
int nx = i + dx[k];
int ny = j + dy[k];
e[nx][ny] ^= 1;
}
}
}
}
void solve() {
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
cin >> e[i][j];
}
}
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
dfs(i, j, 0);
}
}
cout << res << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号