开关问题:计算达到指定状态的方法数量
给定 N 个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开。你的目标是经过若干次开关操作后使得最后 N 个开关达到一个特定的状态。对于任意一个开关,最多只能进行一次开关操作。你的任务是,计算有多少种可以达到指定状态的方法。(不计开关操作的顺序)
输入
输入第一行有一个数 K,表示以下有 K 组测试数据。
每组测试数据的格式如下:
第一行 一个数 N(0 < N < 29) 第二行 N 个 0 或者 1 的数,表示开始时 N 个开关状态。 第三行 N 个 0 或者 1 的数,表示操作结束后 N 个开关的状态。 接下来 每行两个数 I J,表示如果操作第 I 个开关,第 J 个开关的状态也会变化。每组数据以 0 0 结束。
输出
如果有可行方法,输出总数,否则输出“Oh,it's impossible~!!” 不包括引号
样例输入
2
3
0 0 0
1 1 1
1 2
1 3
2 1
2 3
3 1
3 2
0 0
3
0 0 0
1 0 1
1 2
2 1
0 0
样例输出
4
Oh,it's impossible~!!
提示
第一组数据的说明:
一共以下四种方法:
操作开关1 操作开关2 操作开关3 操作开关1、2、3 (不记顺序)
C++,只能使用内置 Main() 内容:以下是使用 C++ 编写的解决方案:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int N;
vector<int> initial_state;
vector<int> target_state;
vector<vector<int>> adjacency_list;
vector<bool> visited;
// 深度优先搜索函数
void dfs(int idx) {
visited[idx] = true;
for (int i = 0; i < adjacency_list[idx].size(); i++) {
int neighbor = adjacency_list[idx][i];
if (!visited[neighbor]) {
if (initial_state[neighbor] != target_state[neighbor]) {
initial_state[neighbor] = 1 - initial_state[neighbor];
}
dfs(neighbor);
}
}
}
// 判断是否存在解决方案
bool isPossible() {
for (int i = 0; i < N; i++) {
if (initial_state[i] != target_state[i]) {
return false;
}
}
return true;
}
// 计算可行方法的数量
int calculateMethods() {
int count = 0;
for (int i = 0; i < N; i++) {
if (!visited[i]) {
if (initial_state[i] != target_state[i]) {
initial_state[i] = 1 - initial_state[i];
}
dfs(i);
count++;
}
}
return count;
}
int main() {
int K;
cin >> K;
while (K--) {
cin >> N;
initial_state.resize(N);
target_state.resize(N);
adjacency_list.resize(N);
visited.resize(N);
for (int i = 0; i < N; i++) {
cin >> initial_state[i];
}
for (int i = 0; i < N; i++) {
cin >> target_state[i];
}
int I, J;
while (cin >> I >> J && I && J) {
adjacency_list[I-1].push_back(J-1);
adjacency_list[J-1].push_back(I-1);
}
fill(visited.begin(), visited.end(), false);
if (isPossible()) {
int count = calculateMethods();
cout << count << endl;
} else {
cout << "Oh,it's impossible~!!" << endl;
}
initial_state.clear();
target_state.clear();
adjacency_list.clear();
visited.clear();
}
return 0;
}
该算法首先通过深度优先搜索(DFS)来模拟开关操作,同时记录已经访问过的开关。如果最终达到目标状态,则计算可行方法的数量。如果无法达到目标状态,则输出"Oh,it's impossible~!!"。
注意事项:
- 输入第一行为测试数据的数量 K,接下来是 K 组测试数据。
- 每组测试数据的第一行为 N,表示开关的数量。
- 每组测试数据的第二行为 N 个 0 或 1 的数,表示开始时 N 个开关的状态。
- 每组测试数据的第三行为 N 个 0 或 1 的数,表示操作结束后 N 个开关的状态。
- 每组测试数据的接下来的行为相联系的开关对,以 0 0 结束。
- 输出每组测试数据的可行方法的数量,或者输出"Oh,it's impossible~!!"。
原文地址: https://www.cveoy.top/t/topic/pige 著作权归作者所有。请勿转载和采集!