当前位置: 首页 > web >正文

[蓝桥杯]小计算器

小计算器

题目描述

模拟程序型计算器,依次输入指令,可能包含的指令有

  1. 数字:'NUMX',X 为一个只包含大写字母和数字的字符串,表示一个当前进制的数。

  2. 运算指令:'ADD','SUB','MUL','DIV','MOD',分别表示加减乘,除法取商,除法取余。

  3. 进制转换指令:'CHANGE K',将当前进制转换为 K 进制(2≤K≤362≤K≤36)。

  4. 输出指令:'EQUAL',以当前进制输出结果。

  5. 重置指令:'CLEAR',清除当前数字。

指令按照以下规则给出:

数字,运算指令不会连续给出,进制转换指令,输出指令,重置指令有可能连续给出。

运算指令后出现的第一个数字,表示参与运算的数字。且在该运算指令和该数字中间不会出现运算指令和输出指令。

重置指令后出现的第一个数字,表示基础值。且在重置指令和第一个数字中间不会出现运算指令和输出指令。

进制转换指令可能出现在任何地方。

运算过程中中间变量均为非负整数,且小于 263263。

以大写的'A'~'Z'表示 10~35。

输入描述

第 1 行:1 个nn(1≤n<5×1051≤n<5×105),表示指令数量。

第 2 ⋯n+1⋯n+1行:每行给出一条指令。指令序列一定以'CLEAR'作为开始,并且满足指令规则。

初始默认的进制是十进制。

输出描述

依次输出每一次 'EQUAL' 得到的结果。

输入输出样例

示例

输入

7
CLEAR
NUM 1024
CHANGE 2
ADD
NUM 100000
CHANGE 8
EQUAL

输出

2040

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

总通过次数: 1075  |  总提交次数: 1304  |  通过率: 82.4%

难度: 困难   标签: 2017, 模拟, 国赛

算法思路:状态机与进制转换

本问题需要实现一个支持多进制运算的程序型计算器,核心挑战在于:

  1. ​多进制处理​​:支持2-36进制转换和数值表示
  2. ​状态管理​​:需要跟踪当前数值、操作符和进制状态
  3. ​大数运算​​:中间变量需支持2⁶³范围内的整数运算
  4. ​指令序列处理​​:按特定规则处理指令序列

采用​​状态机模型​​结合​​进制转换函数​​实现:

算法步骤

  1. ​初始化状态​​:

    • 当前值 current = 0
    • 操作符 op = ""
    • 进制 base = 10
    • 重置标志 after_clear = true
  2. ​指令处理​​:

    • ​CLEAR​​:重置状态,标记下一个NUM为基础值
    • ​NUM X​​:
      • 若在CLEAR后,设为当前值
      • 若有待处理操作符,执行运算
    • ​运算指令​​:记录操作符,等待操作数
    • ​CHANGE K​​:更新当前进制
    • ​EQUAL​​:将当前值转换为当前进制字符串输出
  3. ​进制转换​​:

    • 字符串→数值:按进制解析字符串
    • 数值→字符串:除基取余法转换

完整代码实现

#include <iostream>
#include <string>
#include <cctype>
#include <vector>
#include <algorithm>
using namespace std;// 字符串转数值(支持2-36进制)
long long strToNum(const string& s, int base) {long long num = 0;for (char c : s) {int digit = isdigit(c) ? c - '0' : c - 'A' + 10;num = num * base + digit;}return num;
}// 数值转字符串(支持2-36进制)
string numToStr(long long num, int base) {if (num == 0) return "0";string res;bool negative = num < 0;if (negative) num = -num;while (num) {int digit = num % base;res += (digit < 10) ? ('0' + digit) : ('A' + digit - 10);num /= base;}if (negative) res += '-';reverse(res.begin(), res.end());return res;
}int main() {ios::sync_with_stdio(false);cin.tie(0);int n;cin >> n;cin.ignore(); // 清除换行符long long current = 0;   // 当前数值string op = "";          // 当前操作符int base = 10;           // 当前进制bool after_clear = true; // CLEAR后标记for (int i = 0; i < n; i++) {string command;getline(cin, command);// 指令类型判断if (command == "CLEAR") {current = 0;op = "";after_clear = true;} else if (command.substr(0, 3) == "NUM") {string num_str = command.substr(4);long long num = strToNum(num_str, base);if (after_clear) {current = num;after_clear = false;} else if (!op.empty()) {if (op == "ADD") current += num;else if (op == "SUB") current -= num;else if (op == "MUL") current *= num;else if (op == "DIV") current /= num;else if (op == "MOD") current %= num;op = "";}}else if (command == "ADD") op = "ADD";else if (command == "SUB") op = "SUB";else if (command == "MUL") op = "MUL";else if (command == "DIV") op = "DIV";else if (command == "MOD") op = "MOD";else if (command.substr(0, 6) == "CHANGE") {base = stoi(command.substr(7));}else if (command == "EQUAL") {cout << numToStr(current, base) << endl;}}return 0;
}

代码解析

  1. ​核心函数​​:

    • strToNum():将字符串按指定进制转换为数值
    • numToStr():将数值转换为指定进制的字符串
  2. ​状态管理​​:

    • current:存储当前计算值
    • op:记录待处理的运算操作
    • after_clear:标记CLEAR后的特殊状态
  3. ​指令处理流程​​:

    • 使用getline读取完整指令
    • substr提取指令参数
    • 状态转换驱动计算过程
  4. ​进制转换​​:

    • 支持2-36进制(0-9,A-Z)
    • 正确处理负数和零值

实例验证(题目样例)

​输入​​:

7
CLEAR
NUM 1024      // 十进制1024
CHANGE 2      // 转为二进制
ADD           // 加法操作
NUM 100000    // 二进制100000 = 十进制32
CHANGE 8      // 转为八进制
EQUAL         // 输出结果

​处理过程​​:

  1. CLEAR:重置状态(current=0, after_clear=true)
  2. NUM 1024:设为当前值(current=1024)
  3. CHANGE 2:进制改为2
  4. ADD:设置操作符为加法
  5. NUM 100000
    • 将"100000"从二进制转为十进制:32
    • 执行加法:1024 + 32 = 1056
  6. CHANGE 8:进制改为8
  7. EQUAL:将1056转为八进制 → 2040

​输出​​:2040 ✓

注意事项

  1. ​进制边界处理​​:

    • 确保进制K在2-36范围内
    • 非法字符检测(如二进制出现'2')
  2. ​数值范围​​:

    • 使用long long(64位)存储中间结果
    • 检查运算溢出(题目保证<2⁶³)
  3. ​特殊运算​​:

    • 除法/取模时除数不能为0
    • 负数处理(题目要求非负整数)
  4. ​状态一致性​​:

    • CLEAR后必须重置操作符状态
    • 确保NUM指令在正确上下文中执行

多方位测试点

​测试类型​​测试数据​​预期结果​​验证要点​
基本运算ADD后接NUM 5正确求和基本运算功能
进制转换CHANGE 16NUM A十进制10字母数字转换
连续重置连续CLEAR指令状态正确重置状态机稳定性
边界数值NUM 9223372036854775807正确处理大数支持(2⁶³-1)
非法操作符UNKNOWN指令忽略或报错错误指令处理
除数为零DIV后接NUM 0异常处理除零保护机制
混合进制运算十进制+二进制值正确结果进制转换一致性
长指令序列10⁵条指令压力测试1秒内完成性能优化

优化建议

  1. ​预编译指令表​​:

    unordered_map<string, function<void()>> cmd_map = {{"CLEAR", [&](){ /* CLEAR处理 */ }},{"ADD",   [&](){ op = "ADD"; }}// ...其他指令
    };
  2. ​进制转换优化​​:

    // 使用查表法加速转换
    const char digits[36] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'
    };
  3. ​运算批处理​​:

    // 支持连续运算(需修改题目规则)
    if (!op.empty() && !after_clear) {execute_pending_operation();
    }
  4. ​错误处理增强​​:

    try {base = stoi(command.substr(7));if (base < 2 || base > 36) throw out_of_range("");
    } catch (...) {cerr << "Invalid base: " << command.substr(7) << endl;
    }
  5. ​内存优化​​:

    // 预留指令存储空间
    vector<string> commands;
    commands.reserve(n);
http://www.xdnf.cn/news/11905.html

相关文章:

  • Git-git跟踪大文件
  • Git的使用技巧
  • hive 3集成Iceberg 1.7中的Java版本问题
  • HarmonyOS NEXT应用开发-Notification Kit(用户通知服务)更多系统能力
  • JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/等待通知机制/锁消除
  • Quipus系统的视频知识库的构建原理及使用
  • C++ 新特性详解:Lambda 表达式全解析(含实战案例)
  • 计算机视觉处理----OpenCV(从摄像头采集视频、视频处理与视频录制)
  • OpenCV CUDA模块图像处理------创建一个模板匹配(Template Matching)对象函数createTemplateMatching()
  • 自动化生产线,IT部署一站式解决方案-Infortrend KS私有云安全,一机多用
  • [蓝桥杯]模型染色
  • 软珊瑚成分 CI-A:靶向口腔癌细胞的 “氧化利剑” 与 ERK 密码
  • 如何借助Hyper - V在Windows 10中构建安全软件测试环境
  • 编译一个Mac M系列可以用的yuview
  • 设计模式-迪米特法则
  • 2025年- H69-Lc177--78.子集(回溯,组合)--Java版
  • 2025年想冲网安方向,该考华为安全HCIE还是CISSP?
  • 界面组件DevExpress WPF中文教程:Grid - 如何识别行和卡片?
  • 深度解析Mysql中MVCC的工作机制
  • 每日Prompt:每天上班的状态
  • UE 材质基础第三天
  • Spring AI Tool Calling
  • SecureCRT 设置超时自动断开连接时长
  • Pluto论文阅读笔记
  • 双流芯谷元宇宙战略落子,智慧园区建设迈入数字孪生时代
  • 【统计方法】树模型,ensemble,bagging, boosting
  • GlobalSign、DigiCert、Sectigo三种SSL安全证书有什么区别?
  • JavaWeb:前端工程化-ElementPlus
  • 设计模式杂谈-模板设计模式
  • 题山采玉:Day2