news 2026/10/14 21:20:41

CSP-J 2022 真题 逻辑表达式 题解(普及+/提高)|读完题再动手,分就稳了

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CSP-J 2022 真题 逻辑表达式 题解(普及+/提高)|读完题再动手,分就稳了

今天看 CSP-J 2022 的这道题,考点是模拟。

题目来源:ACGO A697 | 洛谷 P8815
难度定位:普及+/提高 | 通过率:47.94%

一、题目信息

题目名称:逻辑表达式

所属赛事:2022 年 CSP-J 组复赛

官方难度:普及+/提高

涉及知识点:模拟、栈

题目链接:https://www.acgo.cn/problemset/info/697

洛谷编号:P8815(同一道题,两个平台均可提交,代码通用)

易错点(很多人栽在这)

  • 按题意逐步实现时,把每个操作拆成独立步骤,别把多个条件揉进一个式子
  • 规则里的『首次满足』『优先最早』这类措辞要落实成具体的比较顺序

题意简述

题意其实很直白:

逻辑表达式是计算机科学中的重要概念和工具,包含逻辑值、逻辑运算、逻辑运算优先级等内容。

在一个逻辑表达式中,元素的值只有两种可能:0(表示假)和 1(表示真)。元素之间有多种可能的逻辑运算,本题中只需考虑如下两种:“与”(符号为&)和“或”(符号为|)。其运算规则如下:

0&0 = 0 & 1 = 1 & 0 = 0, 1 & 1 = 1

0∣0=0,0 | 1 = 1 | 0 = 1 | 1 = 1

在一个逻辑表达式中还可能有括号。规定在运算时,括号内的部分先运算;两种运算并列时,&运算优先于|运算;同种运算并列时,从左向右运算。

比如,表达式0|1&0的运算顺序等同于0|(1&0);表达式0&1&0|1的运算顺序等同于((0&1)&0)|1。

此外,在 C++ 等语言的有些编译器中,对逻辑表达式的计算会采用一种“短路”的策略:在形如a&b的逻辑表达式中,会先计算a部分的值,如果 a = 0,那么整个逻辑表达式的值就一定为 0,故无需再计算b部分的值;同理,在形如a|b的逻辑表达式中,会先计算a部分的值,如果 a = 1,那么整个逻辑表达式的值就一定为 1,无需再计算b部分的值。

现在给你一个逻辑表达式,你需要计算出它的值,并且统计出在计算过程中,两种类型的“短路”各出现了多少次。需要注意的是,如果某处“短路”包含在更外层被“短路”的部分内则不被统计,如表达式1|(0&1)中,尽管0&1是一处“短路”,但由于外层的1|(0&1)本身就是一处“短路”,无需再计算0&1部分的值,因此不应当把这里的0&1计入一处“短路”。

前置知识

这题要用到的工具不多,但有一个容易忘,先过一遍。

按题意一步步走

模拟题不考算法,考的是「把话翻译成代码」的耐心。读题时把变量、循环、边界一条条列出来,再动手写,比边写边想快得多。

后进先出

栈的特点是最后放进去的最先拿出来。遇到「括号匹配」「表达式求值」「找最近的更大元素」这类题,先想栈。

二、思路分析

这题官方难度普及+/提高,前半场到中场比较稳妥。

思路的入口在哪里?

这道题大部分人貌似都是表达式求值的,不过其实可以有更简单的做法,直接从左到有一遍扫过去即可。

首先,你先想清楚在什么情况下一段表达式没有贡献。如果是 0& ,则在下一次出现 | 或和它前面 一个 (匹配的) 之后才会产生贡献,而前面一段则为 0。如果是 1|,则出现和它前面 一个 (匹配的) 之后才会产生贡献。

其次,我们要想清楚优先级怎么搞,但事实上,优先级并不会影响到结果,因为如果出现 1|,则会一直调到后面的括号,所以它的优先级一定高于 &,如果是 0|,那它并不会对结果产生影响,& 同理。如果不是很明白上面说的,你可以模拟一下数据:
0&(1|0)|(1|1|1&0)
出现 0&,则一直跳到 0&(1|0)|,第一个 | 因为在括号内,所以可以忽略,此时变成 0|(1|1|1&0),因为 0|不会产生贡献,所以表达式可以变为 (1|1|1&0),直接一口气跳到最后的括号,于是就做完了。

三、完整代码

#include <iostream> #include <vector> #include <algorithm> using namespace std; // CSP-J 2022 逻辑表达式(A697) // 给定中缀逻辑表达式(含 & | ( )),求值并统计两种短路的次数。 // 做法:递归下降解析表达式,返回 (值, & 短路次数, | 短路次数)。 // - 先解析由 | 连接的若干 & 项;对 | :若左值为 1,则短路,右值不再求值 // - 再解析由 & 连接的若干原子;对 & :若左值为 0,则短路,右值不再求值 // 注意:被短路的部分里即使有短路也不计入。 struct Res { int val; long long cntAnd; long long cntOr; }; string s; int pos; Res parseOr(); // 前向声明 Res parseAtom() { if (s[pos] == '(') { ++pos; // 跳过 '(' Res r = parseOr(); ++pos; // 跳过 ')' return r; } int v = s[pos] - '0'; ++pos; Res r; r.val = v; r.cntAnd = 0; r.cntOr = 0; return r; } Res parseAnd() { Res cur = parseAtom(); while (pos < (int)s.size() && s[pos] == '&') { ++pos; if (cur.val == 0) { // 短路:右侧不再求值,但表达式结构仍要跳过 // 为了正确跳过一个原子(可能带括号),这里仍需要解析但不计短路 Res rhs = parseAtom(); (void)rhs; cur.cntAnd += 1; } else { Res rhs = parseAtom(); cur.val = cur.val & rhs.val; cur.cntAnd += rhs.cntAnd; cur.cntOr += rhs.cntOr; } } return cur; } Res parseOr() { Res cur = parseAnd(); while (pos < (int)s.size() && s[pos] == '|') { ++pos; if (cur.val == 1) { Res rhs = parseAnd(); (void)rhs; cur.cntOr += 1; } else { Res rhs = parseAnd(); cur.val = cur.val | rhs.val; cur.cntAnd += rhs.cntAnd; cur.cntOr += rhs.cntOr; } } return cur; } int main() { cin >> s; pos = 0; Res r = parseOr(); cout << r.val << '\n' << r.cntAnd << ' ' << r.cntOr << '\n'; return 0; }

四、代码分段拆解

完整代码在上面,下面按功能分块解释。

头文件与全局变量

先把用到的头文件和全局变量放上来。全局变量在竞赛里很常用,好处是函数之间共享方便,代价是要小心初始化和被意外改写。

#include <iostream> #include <vector> #include <algorithm>
using namespace std; struct Res { int val; long long cntAnd; long long cntOr; }; string s; int pos; int v = s[pos] - '0';

主体逻辑

主体部分按顺序完成读入、计算、输出。main函数尽量保持线性,把复杂的逻辑拆成独立函数,出问题时更容易定位。

边界处理

这类题最容易在边界上翻车:最小值、最大值、只剩一个元素的情况,都在脑中过一遍。

五、实例模拟

光看代码容易虚,用样例实测一遍最踏实。

样例 1

输入:

0&(1|0)|(1|1|1&0)

输出:

1 1 2

样例 2

输入:

(0|1&0|1|1|(1|1))&(0&1&(1|0)|0|1|0)&0

输出:

0 2 3

以第一组样例为例,输入是0&(1|0)|(1|1|1&0),正确输出是1、1 2。建议把这两行数据抄在纸上,用上面的代码手动走一遍,重点看循环变量怎么变化、答案在哪一步被更新。能自己推出来的东西,比看懂代码印象深得多。

六、踩坑总结

最后总结几个要点。

  1. 按题意逐步实现时,把每个操作拆成独立步骤,别把多个条件揉进一个式子
  2. 规则里的『首次满足』『优先最早』这类措辞要落实成具体的比较顺序

另外提醒一句:这题在 CSP-J 2022 里是普及+/提高难度,考场上如果没有把握拿满分,先把暴力写法交上去拿到部分分,再回头优化。CSP 是打分制,空着不写才是最亏的。

七、知识点拓展

这题的核心是模拟。

模拟题在 CSP 里属于「必须拿满」的部分。它的训练价值不在于算法,而在于把一段自然语言描述准确翻译成代码的能力。训练方法很简单:读完题先不写代码,用中文把步骤一步步列出来,再逐条翻译。

建议的练习路径:

  1. 先把本题独立写一遍,不看代码,遇到卡壳再看提示
  2. 换个平台提交(ACGO 和洛谷都试试),确保代码在两个平台都能过
  3. 找两到三道同类型的题练手,巩固这类问题的识别能力
  4. 本题还涉及 栈,建议一并复习

八、适用人群

这道题的适用面:

  • 已经能写基础题,想在 CSP-J 里稳定拿到中档分的同学
  • 学完基础 DP 或图论,需要真题检验掌握程度的同学
  • 想弄明白模拟类问题标准解法的同学

代码有任何问题欢迎指正,我会及时更新。

关于这个系列

这是「CSP 真题逐题精讲」的第 30 篇。我会按年份从 2019 一路刷到 2025,
CSP-J 和 CSP-S 全覆盖。每篇都给:双平台题号(ACGO + 洛谷)+ 逐行代码拆解 + 真实样例模拟。

跟着刷完这一套,CSP 第一轮的选择题和基础题基本就稳了。

下一篇:CSP-S 2022 策略游戏(普及+/提高)

👉 关注我,不错过后续更新。评论区告诉我你现在刷到哪一年了,我看看能不能按大家的进度调整更新节奏。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 21:18:52

医学生转行AI+医疗,斩获礼来30K Offer,揭秘复合人才职业新路径

本文分享一位医学生成功转型AI医疗领域&#xff0c;获得礼来30K岗位的经验。文章指出&#xff0c;随着AI技术进入医疗行业&#xff0c;懂医学又懂AI的复合型人才成为稀缺资源。作者通过三个阶段引导医学生建立AI思维、学习AI应用能力、重新定位职业标签&#xff0c;最终成功转型…

作者头像 李华
网站建设 2026/10/14 21:18:43

Halcon 图像增强(Image Enhancement)详解与算子说明

Halcon 图像增强(Image Enhancement)详解与算子说明 参考来源:Halcon 17.12 Operator Reference — Enhancement / Filter / Morphology / FFT 章节、Solution Guide I (Basics) 适用版本:Halcon 17.12(主基准)/ 20.11 / 22.11 / 24.05 官方示例路径:Applications/ 及 s…

作者头像 李华
网站建设 2026/10/14 21:18:02

易语言取CPU序列号并生成特征字:从WMI查询到软件授权实践

做软件授权、设备绑定这一类功能的朋友&#xff0c;一定绕不开“机器码”这个词。机器码的源头有很多种&#xff0c;CPU序列号是最常被提到的一个。“易语言取CPU序列号特征字”要干什么&#xff1f;简单说&#xff0c;就是通过易语言读取CPU的硬件标识&#xff0c;再把这段原始…

作者头像 李华
网站建设 2026/10/14 21:16:19

C#实现Visio风格图形拖拽:状态机驱动的图形系统设计

简介&#xff1a;本资源是一套基于C# Windows Forms实现的轻量级图形化拖拽开发示例&#xff0c;面向GUI初学者、OA系统开发者及流程图工具学习者&#xff0c;解决在桌面应用中构建可交互节点与动态连线的核心需求。项目完整实现了类似Visio的节点拖拽、连接线实时跟随、自定义…

作者头像 李华
网站建设 2026/10/14 21:14:51

大厂校招薪资大揭秘:小白程序员必看,收藏这份热门岗位薪资指南!

本文汇总了字节跳动、腾讯、阿里巴巴等热门大厂校招薪资情况&#xff0c;涵盖前后端开发、AI/Agent方向、测开等岗位。数据来源于往届案例及公开信息&#xff0c;详细展示了不同级别薪资待遇及福利。文章提醒求职者在选择Offer时&#xff0c;不仅要关注总包&#xff0c;还要了解…

作者头像 李华
网站建设 2026/10/14 21:14:14

ArkUI Canvas:巡检曲线缺测断点分段绘制与边界守护【鸿蒙心迹】

项目&#xff1a;PulseTrace&#xff5c;页面&#xff1a;TraceReviewPage&#xff5c;任务&#xff1a;PT-2907 说明&#xff1a;本文全部数据、日志和画面均为人工构造的演示&#xff0c;未声称进行 DevEco 编译、真机采集或医疗检测。 一、这条折线最容易画错的不是颜色 做离…

作者头像 李华