试题 历届试题
问题描述
模拟程序型计算器,依次输入指令,可能包含的指令有
1. 数字:‘NUM X’,X为一个只包含大写字母和数字的字符串,表示一个当前进制的数
2. 运算指令:‘ADD’,‘SUB’,‘MUL’,‘DIV’,‘MOD’,分别表示加减乘,除法取商,除法取余
3. 进制转换指令:‘CHANGE K’,将当前进制转换为K进制(2≤K≤36)
4. 输出指令:‘EQUAL’,以当前进制输出结果
5. 重置指令:‘CLEAR’,清除当前数字
指令按照以下规则给出:
数字,运算指令不会连续给出,进制转换指令,输出指令,重置指令有可能连续给出
运算指令后出现的第一个数字,表示参与运算的数字。且在该运算指令和该数字中间不会出现运算指令和输出指令
重置指令后出现的第一个数字,表示基础值。且在重置指令和第一个数字中间不会出现运算指令和输出指令
进制转换指令可能出现在任何地方
运算过程中中间变量均为非负整数,且小于2^63。
以大写的’A’'Z’表示1035
输入格式
第1行:1个n,表示指令数量
第2…n+1行:每行给出一条指令。指令序列一定以’CLEAR’作为开始,并且满足指令规则
输出格式
依次给出每一次'EQUAL'得到的结果
样例输入
7
CLEAR
NUM 1024
CHANGE 2
ADD
NUM 100000
CHANGE 8
EQUAL
样例输出
2040
想法:
一题很基本的模拟题,但是本身所存在的坑洞还是有点多的,最主要的是要细心去看题目,还是很适合我这种比较粗心的人拿来练习的。题目大概的意思就是模拟一个可以输出转换进制计数器,要求计算加减乘除以及取余,输入会有不同的进制数,所以得在输入的时候判断进制转化为10进制来进行计算。
因此只要判断输入的条件为什么来进行基本的操作就行,但要注意 CLEAR 会默认将之前的所有操作除了进制以外全部删除,还有一些例如判断的进制超过10进制用大写字母,输出为0的特殊判断等小坑洞。
代码:
#include<iostream>
#include<string>
#include<map>
using namespace std;
typedef long long ll;
ll num=0,in=10,fuck=0;
map<char,int> ma;
string age,addoj;
char book[100];
ll zhuang(){
ll bei=1;
ll chun=0;
for(ll i=age.size()-1;i>=0;i--){
chun+=ma[age[i]]*bei;
bei*=in;
}
return chun;
}
void num1(){
cin>>age;
if(fuck==0){
num=zhuang();fuck=1;
}
else{
if(addoj=="ADD"){
num+=zhuang();
}
if(addoj=="SUB"){
num-=zhuang();
}
if(addoj=="MUL"){
num*=zhuang();
}
if(addoj=="DIV"){
num/=zhuang();
}
if(addoj=="MOD"){
num%=zhuang();
}
}
}
void out(){
string sb="";
ll num1=num;
if(num1==0){
cout<<"0"<<endl;
return;
}
else{
while(num1){
sb=book[num1%in]+sb;
num1/=in;
}
cout<<sb<<endl;
}
}
int main(){
ll sum,src;
string s;
cin>>sum;
for(ll i=0;i<=9;i++){
book[i]=i+'0';
ma[i+'0']=i;
}
for(char i='A';i<='Z';i++){
book[i-'A'+10]=i;
ma[i]=10-'A'+i;
}
while(sum--){
cin>>s;
if(s=="CLEAR"){
num=0;fuck=0;
}
else if(s=="NUM"){
num1();
}
else if(s=="CHANGE"){
cin>>src;in=src;
}
else if(s=="EQUAL"){
out();
}
else if(s=="ADD"''s=="SUB"''s=="MUL"''s=="DIV"''s=="MOD"){
addoj=s;
}
}
return 0;
}