【蓝桥杯】PREV-55 小计算器

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
  模拟程序型计算器,依次输入指令,可能包含的指令有
  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

【题意】设计一个小计算器,能实现:输入非负整数(小于2^36)、加减乘除运算模式、2到36进制的转换、输出、重置(数值和运算模式重置,进制不变!)
【思路】
1、用ans记录当前数值,flag记录当前运算模式,k记录当前进制;
2、用Convert_to_dec函数把k进制的字符串转换成10进制数,用于过程计算;
3、用Convert_to_k函数把10进制数转换成k进制的字符串,用于结果输出;
4、按照要求模拟,注意要用long long

#include<iostream>
#include<string.h>
using namespace std;
#define ll long long
//PREV-55	小计算器
ll Index(ll x, ll k)					//求k的x次方 
{
	ll ans = 1;
	for(ll i = 1; i <= x; i++)
		ans *= k;
	return ans;
}
ll Convert_to_dec(string ss, ll k)		//把k进制的ss转换10进制 
{
	ll ans = 0, len = ss.size();
	for(ll i = 0; i < len; i++)
	{
		ll x = len - i - 1;
		if(ss[i] >= '0' && ss[i] <= '9')
			ans += ((ll)ss[i] - '0') * Index(x, k);
		else if(ss[i] >= 'A' && ss[i] <= 'Z')
			ans += ((ll)ss[i] - 'A' + 10) * Index(x, k);
	}
	return ans;
}
string Convert_to_k(ll ans, ll k)		//把10进制转的ans转换成k进制
{
	string ss;
	if(ans == 0)
		return "0";
	while(ans)
	{
		char tmp;
		if(ans % k < 10)
			tmp = ans % k + '0';
		else if(ans % k >= 10)
			tmp = ans % k + 'A' - 10;
		ss = tmp + ss;
		ans /= k;
	}
	return ss;
}
int main()
{
	ll n, ans = 0, flag = 0, k = 10;	//数值,运算模式,进制 
	cin>>n;
	string s;
	while(n--)
	{
		cin>>s;
		if(s == "CLEAR")		//数值和运算模式重置,进制不变! 
		{
			ans = 0;
			flag = 0;
		}
		else if(s == "CHANGE")
			cin>>k;
		else if(s == "ADD")
			flag = 1;
		else if(s == "SUB")
			flag = 2;
		else if(s == "MUL")
			flag = 3;
		else if(s == "DIV")
			flag = 4;
		else if(s == "MOD")
			flag = 5;
		else if(s == "NUM")
		{
			string ss;
			cin>>ss;
			ll tmp = Convert_to_dec(ss, k);	//把k进制转换10进制 
			if(flag == 0)
				ans = tmp;
			else if(flag == 1)
				ans += tmp;
			else if(flag == 2)
				ans -= tmp;
			else if(flag == 3)
				ans *= tmp;
			else if(flag == 4)
				ans /= tmp;
			else if(flag == 5)
				ans %= tmp; 
		}
		else if(s == "EQUAL")
			cout<<Convert_to_k(ans, k)<<'\n';
	}
	return 0;
}

还有一组测试样例:

/*输入
23
CLEAR
NUM 281659794
ADD
NUM 1722405514
MOD
NUM 660145688
EQUAL
DIV
NUM 19821154
MUL
NUM 922337202603578091
EQUAL
SUB
CHANGE 31
NUM ABO16DF
SUB
NUM 3LJI76O4
ADD
NUM 25RAC4GA
SUB
NUM IPA0SG0J
MOD
NUM 21Q75TT
*/
/*输出
23628244
922337202603578091
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_碗碗儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值