📌  相关文章
📜  门| Sudo GATE 2020 Mock III(2019年1月24日)|问题4(1)

📅  最后修改于: 2023-12-03 15:28:46.575000             🧑  作者: Mango

门| Sudo GATE 2020 Mock III(2019年1月24日)|问题4

问题描述

现有一个模拟电路,它由 $n$ 个 AND 门和 $m$ 个 OR 门组成,每个门有若干输入和一个输出。

其中,输入是输入信号或其他门的输出,输出则是供其他门作为输入的信号或电源或地。

你可以将一个输入或输出和一个 $0$ 或 $1$ 相连,表示这个输入或输出为给定取值。

现在,请你确定是否存在一种方案,使得每个AND门的输出都为 $1$。

输入格式

第 $1$ 行两个整数 $n$,$m$,表示门的个数。

第 $2$行 $m$ 个整数,$c_i$,表示第 $i$ 个或门的输入数量。

接下来 $m$ 行,每行若干个 $0$ 或 $1$,表示第 $i$ 个或门的输入的联接情况。

然后是 $n$ 个 AND 门的输入情况,每行若干个 $0$ 或 $1$。

输出格式

如果能找到一种联接方案,输出 “Yes”。否则输出 “No”。

数据范围

输入数据保证每个输入和输出最多只被联接一次。

$1\leqslant n,m\leqslant110$

示例

输入:

4 4
4 2 2 2
1 2
1 3
1 4
1 2 3 4
1 2
1 3
1 2
1 3

输出:

Yes
解题报告

本题属于模拟电路设计,需要根据输入输出之间的关系求解。

通过数据可以发现:

  • 所有的输入和模拟电路的输出只有通过 OR 门的输出连接才能影响到模拟电路的输出。
  • 对于每个 AND 门都需要至少存在一个 $1$ 的输入才能使输出为 $1$。

根据以上两点可以列出一个简单的算法:

  • 对于每个 OR 门都需要至少存在一个 $1$ 的输入才能使输出为 $1$。
  • 对于每个 AND 门都需要至少存在一个与输入相连且值为 $1$ 的线路。

基于此算法框架,可以使用以下代码实现本题的解题过程:

def main():
    # 1. 读取输入
    n, m = map(int, input().split())
    c = list(map(int, input().split()))

    # 2. 处理或门的输入输出关系
    or_gates = []
    for i in range(m):
        inputs = list(map(int, input().split()))
        or_gate = {
            'inputs': inputs,
            'output': 0,
        }
        or_gates.append(or_gate)

    # 3. 处理 AND 门的输入输出关系
    and_gates = []
    for i in range(n):
        inputs = list(map(int, input().split()))
        and_gate = {
            'inputs': inputs,
            'output': 0,
        }
        and_gates.append(and_gate)

    # 4. 解决问题
    for i in range(m):
        for j in range(c[i]):
            input_idx = or_gates[i]['inputs'][j]
            if and_gates[input_idx - 1]['output'] == 0:
                or_gates[i]['output'] = 1
                break

    for i in range(n):
        if all([or_gates[x - 1]['output'] == 1 for x in and_gates[i]['inputs']]):
            and_gates[i]['output'] = 1

    # 5. 检查结果
    if all([x['output'] == 1 for x in and_gates]):
        print('Yes')
    else:
        print('No')

需要注意的是:对于所有的输入和 OR 门的输出都必须使用数字表达(输入从 $1$ 开始编号,输出从 $m+1$ 开始编号),而不能使用字符表达(例如,使用字母 A 表示第一个输入),否则会导致程序出错。

此外,由于本题确保每个输入和输出最多只被联接一次,因此可以通过将输入输出按照数字编号存储来简化代码实现。

完整代码如下: