CCF CSP201903-2二十四点【100分】

#include<iostream>
#include<algorithm>
#include<stack> 
using namespace std;
//本题核心思想:先算乘除、再算加减。
//具体而言如下:
//1.如果遇到+、-,判断下一个运算是*或/,还是+或-。
//如果是*或/,先算乘除;如果是加减,则当前运算符可以直接参加运算 
//2.依据上面的逻辑,则两个运算符总可以计算其中一个参与的值,因此遍历完运算式后,由于先算乘除(遍历过程中算完了) 
//因此,运算符栈中只含有一个加号+或者-号。 
int main(){
	int n;
	scanf("%d",&n);
	string s;
	stack<char> oper;
	stack<int> num;
	getchar();//吸收掉\r\n 
	for(int i=0;i<n;i++){
		getline(cin,s);
		//判断下一次运算结果,需将上一次运算符栈和运算数栈清空 
		while(!oper.empty()) oper.pop(); 
		while(!num.empty()) num.pop();
		int len = s.length();
		//计算当前运算式 
		for(int j=0;j<len;j++){
			//如果是数字,则直接进运算数栈num 
			if(s[j]>='1'&&s[j]<='9') num.push(s[j]-'0');
			//如果是+号 
			else if(s[j]=='+'){
				//则判断下一个运算是否是乘除符号 
				if(s[j+2]=='x'||s[j+2]=='/') {//是,则当前运算符s[j]需要先压入栈,延后运算 
					oper.push(s[j]);
					continue;//跳过当前运算符s[j]的计算 
				}
				else{//否,则当前运算符s[j]可以直接计算 
					int num1 = num.top();//取出栈顶元素 
					num.pop();//将该数字出栈 
					int num2 = s[j+1]-'0';//获取运算符下一个位置处的运算数 
					num1 = num1 + num2;//计算两者的和 
					num.push(num1);//将结果压入栈 
					j=j+1;//判断下一个运算符 
				}
			}else if(s[j]=='-'){//遇到减号-的逻辑类似于+号 
				if(s[j+2]=='x'||s[j+2]=='/'){
					oper.push(s[j]);
					continue;
				}
				else{
					int num1 = num.top();
					num.pop();
					int num2 = s[j+1]-'0';
					num1 = num1 - num2;  //此处是num1-num2 
					num.push(num1);
					j=j+1;
				}
			}
			else if(s[j]=='x'){//当遇到的是乘号运算符,则需要先算乘,直接用当前运算符直接参加运算 
				int num1 = num.top();//获取栈顶的元素 
				num.pop();//将该数字出栈 
				int num2 = s[j+1]-'0';//获取当前运算符的下一个位置处的运算数 
				num1 = num1*num2;//计算两者的乘积 
				num.push(num1);//将计算结果压入栈 
				j = j+1;//判断下一个运算符 
			}else if(s[j]=='/'){//当遇到的是除号,计算逻辑类似于上面的乘号 
				int num1 = num.top();
				num.pop();
				int num2 = s[j+1]-'0';
				num1 = num1/num2;
				num.push(num1);
				j = j+1;
			}
		}
		//for循环结束后,运算数栈里面最多两个数字,运算符栈最多一个运算符
		//只要运算符栈不为空,则需要再进行计算 
		while(!oper.empty()){
			int num1 = num.top();//获取运算符后的运算数 
//			cout<<num1<<endl;
			num.pop();
			int num2 = num.top();//获取运算符前的运算数 
//			cout<<num2<<endl;
			num.pop();
			//判断运算符栈中的运算符的符号,注意,运算符栈的元素不可能是乘除。
			//因为乘除在上面的for循环中一定先运算完了。 
			char op = oper.top(); 
			oper.pop();
			if(op=='+'){//运算符栈中是+号,则两数相加 
				num1= num1+num2;
				num.push(num1);
			}else if(op=='-'){//运算符栈中的是-号,则两数相减 
				num1 = num2-num1;  //注意此处是num2-num1【运算符前的数-运算符后的数】 
				num.push(num1);
			}
		}
//		cout<<num.top()<<endl;
		//判断最后运算数栈的数字是否等于24,是,则输出Yes,否则,输出No 
		if(num.top()==24) cout<<"Yes"<<endl;
		else cout<<"No"<<endl;	
	}
}







  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值