CCF 202009-3 点亮数字人生(拓扑排序)

题目背景
土豪大学的计算机系开了一门数字逻辑电路课,第一个实验叫做“点亮数字人生”,要用最基础的逻辑元件组装出实际可用的电路。时间已经是深夜了,尽管实验箱上密密麻麻的连线已经拆装了好几遍,小君同学却依旧没能让她的电路正常工作。你能帮助她模拟出电路的功能,成功点亮她的数字人生吗?

问题描述
本题中,你需要实现一个简单的数字逻辑电路模拟器。如果你已经有了此方面的基础,可以直接跳过本节。在阅读时,也可以参照前两个样例的图示和解释,这有助于你更好地理解数字逻辑电路的工作原理。

数字逻辑电路是用来传输数字信号(也就是二进制信号)的电路。一般来说,数字逻辑电路可以分为两大类,即组合逻辑(combinational logic)电路和时序逻辑(sequential logic)电路。在本题中,我们仅关注组合逻辑电路。这种电路仅由逻辑门(logical gate)构成。一个逻辑门可以理解为一个多输入单输出的函数,输入端连接至少一个信号,而后经过一定的逻辑运算输出一个信号。常见的逻辑门包括与(AND)、或(OR)、非(NOT)、异或(XOR)等,均与编程语言中的按位运算是对应的。

将一系列的逻辑门连接起来,就能构成具有特定功能的电路。它的功能可能很简单(如一位二进制加法只需要一个异或门),也可能极其复杂(如除法)。无论复杂程度,这类电路的特点是:它不维持任何的状态,任何时刻输出只与输入有关,随输入变化。真实世界中的逻辑器件由于物理规律的限制,存在信号传播延时。为了简单起见,本题中我们模拟的组合逻辑电路不考虑延时:一旦输入变化,输出立刻跟着变化。

考虑到组合逻辑电路的这一特性,设计时不能允许组合环路(combinational loop)的存在,即某逻辑门的输入经过了一系列器件之后又被连接到了自己的输入端。真实世界中,这种做法将导致电路变得不稳定,甚至损坏元器件。因此,你也需要探测可能的环路。需要注意,环路的存在性与逻辑门的具体功能没有任何关系;只要连接关系上存在环路,电路就无法正常工作。

输入格式
输入数据包括若干个独立的问题,第一行一个整数
,满足
。接下来依次是这
个问题的输入,你需要对每个问题进行处理,并且按照顺序输出对应的答案。

每一个问题的输入在逻辑上可分为两部分。第一部分定义了整个电路的结构,第二部分定义了输入和输出的要求。实际上两部分之间没有分隔,顺序读入即可。

第一部分
第一行是两个空格分隔的整数
,分别表示了整个电路的输入和器件的数量,满足
并且
。其中

都是与测试点编号有关的参数。

接下来
行,每行描述一个器件,编号从 1 开始递增,格式如下:

FUNC k L_1 L_2 … L_k
None
其中 FUNC 代表具体的逻辑功能,
表示输入的数量,后面跟着该器件的
个输入端描述
,格式是以下二者之一:

Im:表示第 m 个输入信号连接到此输入端,保证

On:表示第 n 个器件的输出连接到此输入端,保证

所有可能的 FUNC 和允许的输入端数量如下表所述:

FUNC 最少输入数量 最多输入数量 功能描述
NOT 1 1 非
AND 2

OR 2

XOR 2
异或
NAND 2
与非(先全部与后取非)
NOR 2
或非(先全部或后取非)
所有的器件均只有一个输出,但这个输出信号可以被用作多个器件的输入。

第二部分
第一行是一个整数
,表示此电路需要运行
次。每次运行,都会给定一组输入,并检查部分器件的输出是否正确。
满足
,其中
是一个与测试点编号有关的参数。

接下来的
行为输入描述,每一行的格式如下:

I_1 I_2 … I_M
None
每行有
个可能为 0 或 1 的数字,表示各个输入信号(按编号排列)的状态。

接下来的
行为输出描述,每一行的格式如下:

s_i O_1 O_2 … O_s
None
第一个整数
表示需要输出的信号数量。后面共有
个在

之间的数字,表示在对应的输入下,组合逻辑完成计算后,需要输出结果的器件编号。

注意 O 序列不一定是递增的,即要求输出的器件可能以任意顺序出现。

输出格式
对于输入中的
个问题,你需要按照输入顺序输出每一个问题的答案:

如果你检测到电路中存在组合环路,则请输出一行,内容是 LOOP,无需输出其他任何内容。

如果电路可以正常工作,则请输出
行,每一行包含
个用空格分隔的数字(可能为 0 或 1),依次表示“输出描述”中要求的各个器件的运算结果。

样例输入1
1
3 5
XOR 2 I1 I2
XOR 2 O1 I3
AND 2 O1 I3
AND 2 I1 I2
OR 2 O3 O4
4
0 1 1
1 0 1
1 1 1
0 0 0
2 5 2
2 5 2
2 5 2
2 5 2
Data
样例输出1
1 0
1 0
1 1
0 0
Data
样例1说明
本样例只有一个问题,它定义的组合逻辑电路结构如下图所示。其功能是一位全加器,即将三个信号相加,得到一个两位二进制数。要求的器件 2 的输出是向更高位的进位信号,器件 5 的输出是本位的求和信号。

p3.jpg

对于第一组输入 0 1 1,输出是 1 0;对于第二组输入 1 0 1,输出恰好依旧是 1 0(但电路内部状态不同)。

样例输入2
1
2 6
NOR 2 O4 I2
AND 2 O4 O6
XOR 2 O5 O1
NOT 1 O6
NAND 2 O2 O2
AND 2 I1 O3
2
0 0
1 0
3 2 3 4
6 1 2 3 4 5 6
Data
样例输出2
LOOP
Data
样例2说明
本样例也只有一个问题,它定义的组合逻辑电路结构如下图所示。

p4.jpg

这是一个带组合环路的电路,因此无法正常工作。特别地,其中最短的环路有以下三条:

6 - 2 - 5 - 3 - 6
4 - 1 - 3 - 6 - 4
2 - 5 - 3 - 6 - 2
评测用例规模与约定


import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.util.*;public class DigitalMock {static StreamTokenizer st=new StreamTokenizer(new BufferedInputStream(System.in));static int nextInt() throws IOException{st.nextToken();return (int)st.nval;}static String next() throws IOException{st.nextToken();return st.sval;}static int Q;//问题个数static int m;//信号输入个数static int n;//器件个数static Nop nops[]=new Nop[550];static int head[]=new int[550];static int ne[]=new int[50000];static int to[]=new int[50000];static int cnt=1;static int du[]=new int[550];static void init(){//初始化Arrays.fill(head,0);Arrays.fill(nops,null);Arrays.fill(ne,0);Arrays.fill(to,0);Arrays.fill(du,0);cnt=1;}static void add(int u,int v){to[cnt]=v;ne[cnt]=head[u];head[u]=cnt++;}public static void main(String[] args) throws IOException{Q=nextInt();for (int i = 0; i < Q; i++) {init();m=nextInt();n=nextInt();for (int i1 = 1; i1 <=n; i1++) {String type=next();int inputsNum=nextInt();for (int j = 0; j < inputsNum; j++) {String in=next();char t=in.charAt(0);int u=Integer.valueOf(in.substring(1));du[i1]++;//起始输入点if(t=='I'){add(u+n,i1);}//其他器件else{add(u,i1);}}Nop nop = new Nop(type);nops[i1]=nop;}for (int k = 1; k <=m; k++) {nops[k+n]=new Nop("SUPER");}int s=nextInt();List<List<Integer>> inputs = new ArrayList<>();List<List<Integer>> ques = new ArrayList<>();for (int i1 = 0; i1 < s; i1++) {List<Integer> sign = new ArrayList<>();for (int i2 = 0; i2 < m; i2++) {sign.add(nextInt());}inputs.add(sign);}for (int p = 0; p < s; p++) {int num=nextInt();List<Integer> q = new ArrayList<>();for (int i1 = 0; i1 < num; i1++) {q.add(nextInt());}ques.add(q);}if(isLoop()==false){System.out.println("LOOP");continue;}for (int i1 = 0; i1 < s; i1++) {query(inputs.get(i1),ques.get(i1));}}}static void query(List<Integer> input,List<Integer> ques){for (int i = 1; i <=n; i++) {//清空所有信号nops[i].input=new ArrayList<>();}for (int i = 1; i <= input.size(); i++) {nops[i+n].output=input.get(i-1);}topo();ArrayList<Integer> res = new ArrayList<>();for (Integer que : ques) {res.add(nops[que].getOut());}for (int i = 0; i < res.size(); i++) {System.out.printf(res.get(i)+" ");}System.out.println();}static boolean isLoop(){int visnum=0;int rudu[];rudu=du.clone();Queue<Integer> q=new LinkedList<>();for (int i = 1; i <=m+n; i++) {if(rudu[i]==0)q.offer(i);}while (!q.isEmpty()){Integer x = q.poll();//出队visnum++;//访问点+1for(int i=head[x];i!=0;i=ne[i]){int y=to[i];rudu[y]--;if(rudu[y]==0){q.offer(y);}}}return visnum==m+n;}static void topo(){int rudu[];rudu=du.clone();Queue<Integer> q=new LinkedList<>();for (int i = 1; i <=m+n; i++) {if(rudu[i]==0)q.offer(i);}while (!q.isEmpty()){Integer x = q.poll();//出队for(int i=head[x];i!=0;i=ne[i]){int y=to[i];rudu[y]--;nops[y].input.add(nops[x].getOut());if(rudu[y]==0){q.offer(y);}}}}
}
class Nop{//NOT/AND/OR/XOR/NAND/NOR/SUPER(指输入信号节点,超级节点)String type;List<Integer> input;//输入端int output=-1;//输出端public Nop(String type) {this.type = type;this.input=new ArrayList<>();}public int getOut(){//计算输出端结果if(output!=-1) return output;if(type.equals("NOT")){return input.get(0)==0?1:0;}else if(type.equals("SUPER")){return output;}else if(type.equals("AND")){for (Integer integer : input) {if(integer==0) return 0;}return 1;}else if(type.equals("OR")){for (Integer integer : input) {if(integer==1) return 1;}return 0;}else if(type.equals("XOR")){int res=0;for (Integer integer : input) {res^=integer;}return res;}else if(type.equals("NAND")){for (Integer integer : input) {if(integer==0) return 1;}return 0;}else{for (Integer integer : input) {if(integer==1) return 0;}return 1;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/749664.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL基础】MySQL基础操作三

文章目录 &#x1f349;1.联合查询&#x1f95d;笛卡尔积 &#x1f349;2.内连接&#x1f95d;查询单个数据&#x1f95d;查询多个数据 &#x1f349;3.外连接&#x1f349;4.自连接&#x1f349;5.合并查询 &#x1f349;1.联合查询 &#x1f95d;笛卡尔积 实际开发中往往数…

【软件测试】软件测试的基本概念和开发模型

1. 前言 在进行软件测试的学习之前,我们要了解软件测试一些基本概念. 这些基本概念将帮助我们更加明确工作的目标以及软件测试到底要做什么. 2. 软件测试的基本概念 软件测试的基本概念有3个,分别是需求,测试用例和BUG. 2.1 需求 这里的需求还可以分为 用户需求和软件需求,用…

python 第三方库(PyPinyin\shortuuid\json)

PyPinyin库 简介 PyPinyin库是一个支持中文转拼音输出的Python第三方库&#xff0c;它可以根据词组智能匹配最正确的拼音&#xff0c;并且支持多音字&#xff0c;简单的繁体, 注音&#xff0c;多种不同拼音/注音风格的转换。 安装 (framework-learn) C:\Users\zzg>pip …

python类对象

类提供了把数据和功能绑定在一起的方法。创建新类时创建了新的对象 类型&#xff0c;从而能够创建该类型的新 实例。实例具有能维持自身状态的属性&#xff0c;还具有能修改自身状态的方法&#xff08;由其所属的类来定义&#xff09;。 和其他编程语言相比&#xff0c;Python…

QT for Mcu的学习建议

QT for MCU&#xff08;微控制器单元&#xff09;是一个相对较新的领域&#xff0c;它允许在资源受限的微控制器上运行Qt框架&#xff0c;从而为嵌入式设备带来丰富的用户界面和跨平台的开发体验。以下是一些建议&#xff0c;可以帮助你开始学习Qt for MCU&#xff1a; 理解Qt…

从遍历上来说,list是单向的,vector是双向的。这句话对吗

从遍历的角度来说&#xff1a; 对于list来说&#xff0c;虽然它是双向链表&#xff0c;每个节点都包含指向前一个节点和后一个节点的指针&#xff0c;但在实际遍历时&#xff0c;我们通常只能沿着一个方向&#xff08;比如从头到尾或从尾到头&#xff09;进行遍历&#xff0c;因…

图像去噪--(1)

系列文章目录 文章目录 系列文章目录前言一、图像噪声1.1 噪声定义1.2 基本特征 二、按照噪声概率分布分类1.高斯噪声2.泊松噪声 三、去噪算法3.1 线性滤波3.1.1 高斯滤波3.1.2 均值滤波 3.2 非线性滤波3.2.1 中值滤波3.2.2 双边滤波 四、深度学习总结 前言 一、图像噪声 1.1 …

条款09:绝不在析构和构造中调用virtual函数

1.为什么 #include<iostream> using namespace std;class Transaction//交易信息类 {Transaction();virtual void logTransaction()const 0;//交易日志 };Transaction::Transaction() {logTransaction(); }class BuyTransaction : public Transaction//买入操作 {virtu…

Springboot全局异常处理

Springboot全局异常处理 一、不使用全局异常处理器二、全局异常处理器1.自定义常量&#xff08;返回状态码&#xff09;2.手动抛出异常3.编写全局异常处理器4.测试结果 三、全局异常处理方式二1.定义状态码常量2. 定义基础接口&#xff08;面向接口编程&#xff09;3.定义枚举类…

湖南麒麟SSH服务漏洞

针对湖南麒麟操作系统进行漏洞检测时&#xff0c;会报SSH漏洞风险提醒&#xff0c;具体如下&#xff1a; 针对这些漏洞&#xff0c;可以关闭SSH服务&#xff08;前提是应用已经部署完毕不再需要通过SSH远程访问传输文件的情况下&#xff0c;此时可以通过VNC远程登录方法&#x…

JMeter基础 — JMeter聚合报告详解

提示&#xff1a;聚合报告组件的使用和察看结果树组件的使用方式相同。本篇文章主要是详细的介绍一下聚合报告组件内容&#xff0c;不做示例演示。 1、聚合报告介绍 在使用JMeter进行性能测试时&#xff0c;聚合报告(Aggregate Report)可以说是必用的监听器。 &#xff08;1&…

Internet协议的安全性

Internet协议的安全性 文章目录 Internet协议的安全性1. 网络层1. IP*62. ARP*33. ICMP * 3 2. 传输层协议1. TCP1. * SYN-Flood攻击攻击检测* 防御 2. TCP序号攻击攻击 3. 拥塞机制攻击 2. UDP 3. 应用层协议1. DNS攻击*3防范*3: 2. FTP3. TELNET: 改用ssh4. 电子邮件1. 攻击2…

【Javascript编程实操06】1、反转数组和字符串 2、将二维数组转一维数组

前言 1、反转数组和字符串 代码&#xff1a; 实现效果&#xff1a; 2、将二维数组转一维数组 代码&#xff1a; 实现效果&#xff1a; 总结 前言 本次主要是针对Javascript阶段的字符串与数组的实操练习&#xff0c;共有2个实操&#xff0c;大家可以在实操的过程中更加深…

什么时候去检测大数据信用风险比较合适?

什么时候去检测大数据信用风险比较合适?在当今这个数据驱动的时代&#xff0c;大数据信用风险检测已经成为个人的一项重要需求。本文将从贷前检测、信息泄露检测和定期检测三个方面&#xff0c;阐述何时进行大数据信用风险检测较为合适。 一、贷前检测 大数据信用风险检测在贷…

Docker使用(二)Docker安装和常见典型操作

Docker使用(二)Docker安装和常见典型操作 二、软件安装 1、Docker安装 &#xff08;1&#xff09;环境准备 [rootlocalhost ~]# uname -r 3.10.0-327.el7.x86_64 # cat /etc/os-release &#xff08;2&#xff09;卸载旧版本 $ sudo yum remove docker \ ​ docker-cli…

折半搜索.

折半搜索 知识点折半搜索的原理折半搜索的过程 例题题目&#xff1a;世界冰球锦标赛题目描述输入样例输出样例提示 世界冰球锦标赛题解思路代码 知识点 折半搜索的原理 折半搜索是一种技巧&#xff0c;实际上就是将一个次搜索过程分成两次进行&#xff0c;然后将两次搜索的结果…

145 Linux 网络编程1 ,协议,C/S B/S ,OSI 7层模型,TCP/IP 4层模型,

一 协议的概念 从应用的角度出发&#xff0c;协议可理解为“规则”&#xff0c;是数据传输和数据的解释的规则。 典型协议 传输层 常见协议有TCP/UDP协议。 应用层 常见的协议有HTTP协议&#xff0c;FTP协议。 网络层 常见协议有IP协议、ICMP协议、IGMP协议。 网络接口层 常…

作业-逆序和定位

目录 字符串逆序 题目描述 输入 输出 样例 解题思路&#xff1a; 单词倒排 题目描述 输入 输出 样例 解题思路&#xff1a; 首字母大写 题目描述 输入 输出 样例 解题思路&#xff1a; 统计句子中单词个数 题目描述 输入 输出 样例 解题思路&#xff1a; 大小写字母互换 题目描…

springboot“涛宝”大学生二手物品交易商城

摘 要 二十一世纪我们的社会进入了信息时代&#xff0c;信息管理系统的建立&#xff0c;大大提高了人们信息化水平。传统的管理方式对时间、地点的限制太多&#xff0c;而在线管理系统刚好能满足这些需求&#xff0c;在线管理系统突破了传统管理方式的局限性。于是本文针对这一…

Kubernetes operator系列:webhook 知识学习

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 Kubernetes operator学习 系列文章&#xff0c;本节会对 kubernetes webhook 知识进行学习 本文的所有代码&#xff0c;都存储于github代码库&#xff1a;https://github.com/graham924/share-code-operator-st…