问题描述
试题编号: 201903-2
试题名称: 二十四点
时间限制: 1.0s
内存限制: 512.0MB
二十四点是一款著名的纸牌游戏,其游戏的目标是使用 3 个加减乘除运算使得 4 张纸牌上数字的运算结果为 24。
定义每一个游戏由 4个从 1−9 的数字和 3个四则运算符组成,保证四则运算符将数字两两隔开,不存在括号和其他字符,运算顺序按照四则运算顺序进行。
其中加法用符号 + 表示,减法用符号 - 表示,乘法用小写字母 x 表示,除法用符号 / 表示。
在游戏里除法为整除(向下取整),例如 2/3=0,3/2=1,4/2=2,−3/7=−1。
老师给了你 n个游戏的解,请你编写程序验证每个游戏的结果是否为 24。
输入格式
第一行输入一个整数 n。
从第 2行开始到第 n+1 行中,每一行包含一个长度为 7 的字符串,为上述的 24点游戏,保证数据格式合法。
输出格式
包含 n行,对于每一个游戏,如果其结果为 24 则输出字符串 Yes,否则输出字符串 No。
数据范围
输入样例:
10
9+3+4x3
5+4x5x5
7-9-9+8
5x6/5x4
3+5+7+9
1x1+9-9
1x9-5/9
8/5+6x9
6x7-3x6
6x4+4/5
输出样例:
Yes
No
No
Yes
Yes
No
No
No
Yes
Yes
样例解释
9+3+4×3=24
5+4×5×5=105
7-9-9+8=-3
5×6/5×4=24
3+5+7+9=24
1×1+9-9=1
1×9-5/9=9
8/5+6×9=55
6×7-3×6=24
6×4+4/5=24
思路:
看着y总思路写的,一道表达式运算的模板题,算几次考试里二题难度高一点的题,要把这类模板记熟,比赛考试才能灵活应用
用数字栈和运算符栈分别存数字和运算符,要注意的是+、-的优先级比*、/要低,可以用哈希表或者一个字符数组对两者的优先级进行一个表示,在运算符压入栈前要判断栈顶的运算符的优先级,如果栈顶优先级高,需要先进行计算
在eval中,注意两个参与预算的数字a,b是要区分的,因为减法和除法有减(除)数和被减(除)数之分
AC代码:
#include<bits/stdc++.h>
using namespace std;
stack<int> num;
stack<char> op;
int n;
string a;
void eval(){
int b = num.top();num.pop();
int a = num.top();num.pop();
char c = op.top();op.pop();
int res = 0;
if(c == '+') res = a + b;
else if(c == '-') res = a - b;
else if(c == 'x') res = a * b;
else if(c == '/'){
if(a * b >= 0) res = a / b; // 同号,直接除就是向下取整
else{
if(a % b == 0) res = a / b;
else res = a / b - 1; //不同号且不能整除的,向下取整需要减1
}
}
num.push(res);
}
int main(){
unordered_map<char,int> mp;
mp['+'] = mp['-'] = 0;
mp['x'] = mp['/'] = 1;
cin >> n;
for(int i = 0;i < n;i++){
cin >> a;
for(auto k : a){
if(k >= '0' && k <= '9') num.push(k-'0');
else{
while(!op.empty()&&mp[op.top()] >= mp[k]) eval(); //这里要注意,!op.empty()一定要在op.top()之前,要不然会由于op内没有元素,无法使用op.top()而出错
op.push(k);
}
}
while(!op.empty()) eval();
if(num.top() == 24) puts("Yes");
else puts("No");
}
}