给定 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 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录