蓝桥杯历届试题 小计算器
http://lx.lanqiao.cn/problem.page?gpid=T459
问题描述
模拟程序型计算器,依次输入指令,可能包含的指令有
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'表示10~35
输入格式
第1行:1个n,表示指令数量
第2..n+1行:每行给出一条指令。指令序列一定以'CLEAR'作为开始,并且满足指令规则
输出格式
依次给出每一次'EQUAL'得到的结果
样例输入
7
CLEAR
NUM 1024
CHANGE 2
ADD
NUM 100000
CHANGE 8
EQUAL
样例输出
2040
按题意模拟就可以了。由于是整数,所以把所有进制化为十进制计算,省去了自己写运算的东西。输出的时候转再转换一下就可以了。有个坑点是在ADD等运算之间可能转换进制。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll,char> eco;
map<char,ll> deco;
int k=10;
ll ans=0;
char num[99];
void init()
{
for(ll i=0;i<=9;i++)
{
eco[i]=i+'0';
deco[i+'0']=i;
}
for(ll i='A';i<='Z';i++)
{
eco[i-'A'+10]=i;
deco[i]=i-'A'+10;
}
}
ll getnum()
{
ll tmp=1;
ll ret=0;
for(int i=strlen(num)-1;i>=0;i--)
{
ret+=tmp*deco[num[i]];
tmp*=k;
}
return ret;
}
void pout(ll tnum)
{
//cout<<tnum<<endl;
if(tnum==0)
{
printf("0\n");
return;
}
int cnt[99]={0};
while(tnum)
{
if(tnum/k)
{
cnt[++cnt[0]]=tnum%k;
tnum/=k;
}
else
{
cnt[++cnt[0]]=tnum;
tnum/=k;
}
}
for(int i=cnt[0];i>0;i--)
{
printf("%c",eco[cnt[i]]);
}
printf("\n");
}
string inst;
void opr(int x)
{
if(x==1) ans+=getnum();
if(x==2) ans-=getnum();
if(x==3) ans*=getnum();
if(x==4) ans/=getnum();
if(x==5) ans%=getnum();
}
int main()
{
//freopen("input4.txt","r",stdin);
init();
int n;
scanf("%d",&n);
int opra=1;
while(n--)
{
//cout<<n<<':'<<ans<<endl;
cin>>inst;
if(inst=="CLEAR")
{
ans=0;
opra=1;
}
else if(inst=="NUM")
{
scanf("%s",num);
//cout<<ans<<"+-*/%"[opra-1]<<getnum()<<endl;
opr(opra);
}
else if(inst=="CHANGE") scanf("%d",&k);
else if(inst=="ADD") opra=1;
else if(inst=="SUB") opra=2;
else if(inst=="MUL") opra=3;
else if(inst=="DIV") opra=4;
else if(inst=="MOD") opra=5;
else if(inst=="EQUAL") pout(ans);
}
}
发表评论