ACM PKU 1048 Follow My Logic

2023-11-12

2009/04/02 0 Comments
Follow My Logic 题目重述
对于一个逻辑电路和给定的输入值,计算该电路的输出值。该逻辑电路有一个或多个输入端, 零个或多个逻辑门电路,和一个输出端。本题中用标准ASCll字符来表示逻辑电路:横竖导线分别用‘-’和‘|’表示,转折点用‘+’表示,输入端用大写字母‘A’-’Z’表示,输出端用问号‘?’表示,小写字母‘o’表示取反。与门、或门及电路各部分示例如下:
  :/      :/       -:/    -o:/    A-o:/
  : )      : >        : )-            : )o-          : )o-?
  :/      :/       -:/     --:/    B-- :/
与门    或门  带输入输出            输入输出    完整电路
                              的门电路         取反的门电路

输入:
输入数据包含多个输入数据块。每个输入数据块包含以下部分:
一个电路图,以上述形式表示,用只含‘*’的单独一行结束。
多行01字符串,每行对应一组数据,包含26个0或1,分别对应A-Z的值。用只含‘*’的单独一行结束

输出:
对每组输入数据,输出对应的电路输出值。
每个结果占一行。
不同输入数据块的输出结果之间用空行隔开。

这是一道模拟类的题目
第一种思路:
模拟人读逻辑电路的做法,按照逻辑电路的走向确定在门电路的各个输入端的值,计算门电路输出端的值。如此反复,最终求得电路的输出值。
第二种思路:
自上至下,自左至右,顺序求解。
关键:
确定电路在交叉点的走向;
从门电路的一段输入电路转到另一段电路。

根据算法要求需要存储的数据有
1.int row, column 用来表示电路图的行数和最大宽度;
2.int ish, dir 用来表示电路走向(水平或竖直、正向或负向);
2.char logic[100][100] 用来存储逻辑电路图;
3.int state[100][100] 用来存储电路上每一个点的值;
4.int value[26] 用来存储A-Z的值。

确定电路在交叉点的走向
根据题意,没有两个交叉点相邻,一个交叉点周围只有‘-’和‘|’。分两种情况讨论。
if(ish)         //原先为水平方向
         {
              if(x                  dir=1;
              else         //转向上
                  dir=-1;
              ish=0;
              x+=dir;
          }

else     //原先为垂直方向
                {
                    if(y                        dir=1;       //转向右
                    else
                        dir=-1;       //转向左
                    ish=1;
                    y+=dir;
                }

电路分析流程:
通过两个函数hdsearch()和process()的嵌套调用实现。
process() 用于从某一位置根据电路走向计算下一位置的值,直至获得输出结果,或到达某一门电路无法继续。
hdsearch() 用于从某一位置寻找这段电路的开头(字母输入值)。
程序从process()开始,直至某一门电路因另一输入端没有计算而无法继续。调用hdsearch()寻找到另一输入端所在电路的开头,然后调用process()继续计算。如此递归调用,直至获得最终输出结果。
#include
#include
int state[100][100],value[26],row,column,done;
char logic[100][100];

void hdsearch(int x,int y)
{
    int dir,ish;
    void process(int x,int y);
    if(done)return;
    dir=-1;ish=1;
    while(!done)
    {
        if(logic[x][y]>='A'&&logic[x][y]<='Z')
            process(x,y);
        else switch(logic[x][y])
        {
            case '-':
            case 'o':
            case ':':
            case '//':
            case '/':
                y=y+dir;
                break;
            case '|':
                x+=dir;
                break;
            case ')':
            case '>':
                if(state[x-1][y-1]==-1)
                {x--;y--;}
                else if(state[x+1][y-1]==-1)
                {x++;y--;}
                else  
                {
                    if(logic[x][y]==')')
                        state[x][y]=state[x-1][y]&state[x+1][y];
                    else
                        state[x][y]=state[x-1][y]|state[x+1][y];
                    process(x,y);
                }
                break;
            case '+':
                if(ish)
                {
                    if(x                        dir=1;
                    else
                        dir=-1;
                    ish=0;
                    x+=dir;
                }
                else
                {
                    if(y                        dir=1;
                    else
                        dir=-1;
                    ish=1;
                    y+=dir;
                }
                break;
        }
    }
    return;
}

void process(int x,int y)
{
    int dir,ish;
    void hdsearch(int x,int y);
    if(done)return;
    if(logic[x][y]>='A'&&logic[x][y]<='Z')
    {
        state[x][y]=value[logic[x][y]-'A'];
        if(y        {
            ish=1;
            dir=1;
            y++;
            state[x][y]=state[x][y-1];
        }
        else if(y>0&&logic[x][y-1]=='-')
        {
            ish=1;
            dir=-1;
            y--;
            state[x][y]=state[x][y+1];
        }
        else if(x        {
            ish=0;
            dir=1;
            x++;
            state[x][y]=state[x-1][y];
        }
        else if(x>0&&logic[x-1][y]=='|')
        {
            ish=0;
            dir=-1;
            x--;
            state[x][y]=state[x+1][y];
        }
    }
    else
    {
        ish=1;
        dir=1;
    }
    while(!done)
    {
        switch(logic[x][y])
        {
            case '-':
            case ':':
            case ')':
            case '>':
                y+=dir;
                state[x][y]=state[x][y-dir];
                break;
            case 'o':
                y+=dir;
                state[x][y]=state[x][y-dir]^1;
                break;
            case '|':
                x+=dir;
                state[x][y]=state[x-dir][y];
                break;
            case '//':
                if(state[x+2][y]==-1)
                    hdsearch(x+2,y);
                else
                {
                    x++;
                    y++;
                    if(logic[x][y]==')')
                        state[x][y]=state[x-1][y-1]&state[x+1][y-1];
                    else
                        state[x][y]=state[x-1][y-1]|state[x+1][y-1];
                }
                break;
            case '/':
                if(state[x-2][y]==-1)
                    hdsearch(x-2,y);
                else
                {
                    x--;
                    y++;
                    if(logic[x][y]==')')
                        state[x][y]=state[x-1][y-1]&state[x+1][y-1];
                    else
                        state[x][y]=state[x-1][y-1]|state[x+1][y-1];
                }
                break;
            case '+':
                if(ish)
                {
                    if(x                        dir=1;
                    else
                        dir=-1;
                    ish=0;
                    x+=dir;
                    state[x][y]=state[x-dir][y];
                }
                else
                {
                    if(y                        dir=1;
                    else
                        dir=-1;
                    ish=1;
                    y+=dir;
                    state[x][y]=state[x][y-dir];
                }
                break;
            case '?':
                printf("%d/n",state[x][y]);
                done=1;
                break;
        }
    }
    return;
}

int main()
{
    int i,j,flag;
    char c;
    while(scanf("%c",&c)==1)
    {
        column=0;
        for(i=0;(i>0?(c=getchar()):1)&&c!='*';i++)
        {
            if(c=='/n'){i--;continue;}
            logic[i][0]=c;
            for(j=1;(c=getchar())!='/n';j++)
            {
                logic[i][j]=c;
            }
            if(j>column)
                column=j;
            for(;j<100;j++)
                logic[i][j]=' ';
        }
        c=getchar();
        while(c=='/n')c=getchar();
        row=i;
        while(c!='*')
        {
            if(c=='/n')continue;
            value[0]=c-'0';
            for(i=1;i<26;i++)
            {
                value[i]=getchar();
                value[i]-='0';
            }
            c=getchar();
            for(i=0;i                for(j=0;j                    state[i][j]=-1;
            flag=0;
            for(j=0;j                for(i=0;i                    if(logic[i][j]>='A'&&logic[i][j]<='Z')
                    {flag=1;break;}
            done=0;
            process(i,j-1);
            c=getchar();
        }
        printf("/n");
        c=getchar();
    }
    return 0;
}
所有递归调用都在计算出最终结果后才返回,可用简单循环代替。Hdsearch()可作为process()的一个分支的一部分。

总结:
模拟类的程序,可以完全模拟人的思维方式进行,也可以充分利用题目中的简化条件,制定适合计算机的搜索策略。
模拟类的程序,关键要分析处理过程,找出其中的难点进行重点突破。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ACM PKU 1048 Follow My Logic 的相关文章

随机推荐

  • Android之ProgressDialog与自定义LoadingDialog

    最近呢一直进行Android项目的开发 开发过程中发现 以前的好多知识点都想不起来了 都得先去Google一下 进展缓慢 耗时又耗力 所以决定将开发中的知识点慢慢总结下来 以便日后查验 大家在进行网络请求数据的时候 尤其是第一次 是不是也会
  • ESP32CAM连接阿里云物联网平台

    搭建arduino开发环境 这里不多说 网上有很多教程 简单说下我在搭建环境时踩的一些坑 1 在arduino库管理器中下载esp32的库出错 解决方法 搭个梯子下载就行了 2 上传项目报错 这个问题出现的原因是板子连线有问题 在烧录的时候
  • 数据结构时间复杂度T(n)=O(f(n))的含义

    1 首先要明白数量级的表示符号 O 和o 分别代表 同阶和高阶 例 如果a b都是无穷小 高阶 如果lim n gt 0 b a的极限等于0 就说b是比a高阶的无穷小 记作b o a 同阶 如果lim n gt 0 b a的极限等于c c
  • HashMap/ConcurrentHashMap在单线程模式下的性能比较

    起源 阅读源码发现jdk8中ConcurrentHashMap是基于synchronized来加锁实现多线程安全的 但是实现方式上与早期的HashTable又有了很大的区别 虽然都是使用synchronized来加锁 但是锁的粒度不一样 大
  • Python+Pycharm和 VisualStudio C++社区版使用PK及易混淆的语法问题

    这2年都是在用Python 使用环境要么是Python的IDLE UE 要么使用Pycharm 近年来基本上都是使用的Pycharm 期间偶尔阅读一下C 的代码 但一直没安装相关编译器 近来为了研究OpenCV的算法 发现光阅读源代码以及难
  • linux CentOS7 keepalived+LVS(DR)搭建部署

    目录 一 作用 二 环境简介 三 操作步骤 一 作用 使用keepalived解决lvs的单点故障 高可用集群 二 环境简介 1 准备6台虚拟机 2台做LVS主备调度器 2台做web服务器 1台做存储 1台客户机验证 2 LVS主备调度器
  • 如何在pycharm删除多余的空行

    如何在pycharm删除多余的空行 示例 1 使用快捷键Ctrl r 输入 n替换为空 点击Replace all 2 完成效果如下 3 使用快捷键Ctrl Alt L 让它变的更符合PEP8标准
  • 【致敬未来的攻城狮计划】--RA2E1 开发板测评(1)keil环境配置

    前言 1 首先感谢 李肯前辈的活动 从而申请到了RA2L1开发板的测评 2 本文将会简单介绍此开发的Renesas RA2L1 开发板的前期配置 需要注意的是 MDK版本要5 30 以上 MDK下载链接 3 相关资料 链接 https pa
  • iptables防火墙开放方法和常用命令

    开放端口 iptables I INPUT p tcp dport 80 j ACCEPT 保存配置 service iptables save 重启防火墙 service iptables restart 查看状态 service ipt
  • 编译原理——语法分析器(C/C++代码实现)

    0 实验目的 编写一个简单的LL 1 语法分析器 注意 此实验是简化版的LL 1 文法 已给出预测分析表 不需要求FIRST和FOLLOW集 直接根据预测分析表编写程序即可 1 实验要求 根据编译原理理论课中学习的算术表达式文法 以及该文法
  • useMemo与useCallback使用指南

    在介绍一下这两个hooks的作用之前 我们先来回顾一下react中的性能优化 在hooks诞生之前 如果组件包含内部state 我们都是基于class的形式来创建组件 当时我们也知道 react中 性能的优化点在于 调用setState 就
  • Linux部署docker容器(使用root用户登录)

    1 查看linux环境是否存在 podman rpm q podman 2 存在就删除podman dnf erase podman buildah 3 添加仓库 dnf config manager add repo https down
  • Postman之接口返回的数据解析为DDL、DML SQL及树结构数据

    JavaScript的将JSON数组转换为树形结构 第三方返回的JOSN数据我们想要快速的转换为结构化数据存入数据库 一般都需要写程序进行解析入库 对于前期获取 分析数据来说时间成本有点大 基于Postman Test在请求响应后对响应数据
  • 【LeetCode-中等题】429. N 叉树的层序遍历

    文章目录 题目 方法一 二叉树的层序遍历的扩展 题目 方法一 二叉树的层序遍历的扩展 思路和二叉树的层序遍历一样 这一题的关键在于取出每个节点的孩子 for int j 0 j
  • Unity安装(自己安装过程) 2019某一版

    1 进入下面网址 下载Unity 2019 2 13f1 Download Assistant 点击此处跳转 2 下载完成之后 打开压缩包 点击此处 即可安装 不要安装在C盘最好 注意 我这个是2019的 必须要Unity Hub才可以运行
  • 西门子PLC的编程语言的数据类型有哪些

    西门子PLC的编程语言支持多种数据类型 以下是常见的数据类型 1 位 Bit 0或1的数据类型 2 字节 Byte 有8位 Bit 组成的数据类型 3 整型 Integer 有符号的16位整数 2字节 4 双字 Double Word 无符
  • Python表白代码:太秀了,用过的人都找到了对象...【满屏玫瑰盛开】

    导语 暗恋让人受尽委屈 一开始 你是我的秘密 我怕你知道 又怕你不知道 又怕你知道装作不知道 这大概就是暗恋的感受吧 可若是双向奔赴 那简更是甜蜜度爆表 快同小编吃下这波狗粮 跟着上一期的玫瑰花花样表白之后 小编新出了2款新型升级之后的表白
  • #LeetCode刷题——350. 两个数组的交集 II

    难度 easy 1 题目介绍 2 思路分析 第一种方法 双指针法 先对俩个数组进行排序 使用俩个指针 i 和 j 不停遍历nums1和nums2 比较俩个元素的值 如果相等就增加到结果集中 如果 nums1 i lt nums2 j 将 i
  • CTF之流量分析之密码文件

    题目地址 BUUCTF在线评测 题目 深夜里 Hack偷偷的潜入了某公司的内网 趁着深夜偷走了公司的秘密文件 公司的网络管理员通过通过监控工具成功的截取Hack入侵时数据流量 但是却无法分析出Hack到底偷走了什么机密文件 你能帮帮管理员分
  • ACM PKU 1048 Follow My Logic

    ACM PKU 1048 Follow My Logic 2009 04 02 0 Comments Follow My Logic 题目重述 对于一个逻辑电路和给定的输入值 计算该电路的输出值 该逻辑电路有一个或多个输入端 零个或多个逻辑