Loading... “飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有 **16**个把手的冰箱。 已知每个把手可以处于以下两种状态之一:打开或关闭。 只有当所有把手都打开时,冰箱才会打开。 把手可以表示为一个 **4**×**4**的矩阵,您可以改变任何一个位置 **[**i**,**j**]**上把手的状态。 但是,这也会使得第 **i**行和第 **j** 列上的所有把手的状态也随着改变。 请你求出打开冰箱所需的切换把手的次数最小值是多少。 #### 输入格式 输入一共包含四行,每行包含四个把手的初始状态。 符号 `+` 表示把手处于闭合状态,而符号 `-` 表示把手处于打开状态。 至少一个手柄的初始状态是关闭的。 #### 输出格式 第一行输出一个整数 **N**,表示所需的最小切换把手次数。 接下来 **N** 行描述切换顺序,每行输出两个整数,代表被切换状态的把手的行号和列号,数字之间用空格隔开。 **注意** :如果存在多种打开冰箱的方式,则按照优先级整体从上到下,同行从左到右打开。 #### 数据范围 **1**≤**i**,**j**≤**4** #### 输入样例: ``` -+-- ---- ---- -+-- ``` #### 输出样例: ``` 6 1 1 1 3 1 4 4 1 4 3 4 4 ``` ### 思路,深搜 ```c++ #include <bits/stdc++.h> using namespace std; int N = 999, kk; char m[4][4], backup[4][4]; vector<int> ans, ways; void dfs(int x, int y, int step){ if(x == 4){ for(int i = 0; i < 4; i++){ for(int j = 0; j < 4; j++){ if(m[i][j] == '+') return; } } if(ans.empty()){ ans = ways; } if(step < N){ N = step; ans = ways; } return; } if(y == 4){ dfs(x + 1, 0, step); return; } for(int i = 0; i < 4; i++){ m[x][i] == '-' ? m[x][i] = '+' : m[x][i] = '-'; m[i][y] == '-' ? m[i][y] = '+' : m[i][y] = '-'; } m[x][y] == '-' ? m[x][y] = '+' : m[x][y] = '-'; ways.push_back(x + 1); ways.push_back(y + 1); dfs(x, y + 1, step + 1); for(int i = 0; i < 4; i++){ m[x][i] == '-' ? m[x][i] = '+' : m[x][i] = '-'; m[i][y] == '-' ? m[i][y] = '+' : m[i][y] = '-'; } m[x][y] == '-' ? m[x][y] = '+' : m[x][y] = '-'; ways.pop_back(); ways.pop_back(); dfs(x, y + 1, step); } int main(){ for(int i = 0; i < 4; i++){ scanf("%s", &m[i]); } dfs(0, 0, 0); cout << N << endl; for(int i = 0; i < ans.size(); i++){ cout << ans[i] << " "; if(i & 1) cout << endl; } return 0; } ``` Last modification:December 21, 2022 © Allow specification reprint Like 0 如果觉得我的文章对你有用,请随意赞赏
Comment here is closed