二十四点


from CCF-CSP 2019-03-2
Time limit:1s
Memory limit:512MB

二十四点_csp


二十四点_csp_02


这个题目相比于数据结构当中的求后缀表达式再求解表达式是简单很多的,因为没有括号,而且表达式很简单。

乘除运算的优先级高,那么每次遇到乘除号就直接处理,遇到加减号就存起来等待处理,从前往后遍历,将乘除处理完,遍历完后再从前往后处理加减。

最开始我想的是用两个栈来存储待处理数字和符号,但是那样的话,只能从后往前操作,比如5-4+5运算出来结果就是-4,如果我们不将中缀表达式转化成后缀表达式那么肯定是会出错的。

最后我用了两个数组来存储待处理数据,再用两个标记记录存储了多少个数字和符号就可以了。

处理方式举例:
6x4+4/5
最开始遍历到6 数字:6 符号:
然后遍历到x4
乘号直接处理6x4=24 数字:24 符号:
然后遍历到+4
加号待处理 数字:24、4 符号:+
然后遍历到/5
除号直接处理4/5=0 数字:24、0 符号:+

遍历完成过后从前往后处理待处理数据
每次都选出选出前两个数字和前一个符号24+0=24 数字:24 符号:
符号处理完成过后,这个表达式就算处理完了。
ac代码:
#include<iostream>
using namespace std;
int n;
int num[5],note1; //储存数字,note1表示已经存储的位置(从0开始)
char ch[5],note2; //存储符号,note2表示已经存储的位置(从0开始)
int main(){
cin>>n;
while(n--){
int m;char c;note1 = note2 = -1; //初始化两个note
cin>>num[++note1]; //存入每个表达式的第一个数字
for(int i = 1;i <= 3;++i){
cin>>c>>m;
if(c == '+' || c == '-')
num[++note1] = m,ch[++note2] = c; //加减的运算,先存入数组
else{ //乘除的就直接运算
if(c == 'x')
num[note1] *= m;
else
num[note1] /= m;
}
}
for(int i = 0;i < note1;++i) //最后再从前往后处理加减运算
if(ch[i] == '+')
num[i + 1] += num[i];
else
num[i + 1] = num[i] - num[i + 1];
if(num[note1] == 24)
cout<<"Yes\n";
else
cout<<"No\n";
}
return 0;
}