CSP-CCF★★★201903-2二十四点★★★

news2024/12/26 12:04:22

目录

一、问题描述

二、解答

方法一:穷举法(只列举了一部分)

方法二:中缀表达式直接求值,两个栈,一个存放数值,一个存放符号

方法三:将中缀表达式转换为后缀来计算注意:

三、总结


一、问题描述

二、解答

方法一:穷举法(只列举了一部分)

即将所有的情况列举出来,共4*4*4=64种情况,但是我实在列不下去了,就只列举了12种。

建造了一个结构体,里面存放输入的字符串;使用两个vector容器,分别存放数字和符号;另外还弄了一个字符串数组,来存放每行结果yes或no。

注意:string不需要显式初始化,且字符串应该使用双引号。

代码(没有写完):

#include<iostream>
#include<string>
#include<vector>
using namespace std;
struct Data {
	string s;
}str[100];
int main()
{
	int n;
	cin >> n;
	//string str[100];
	for (int i = 0; i <n; i++)
	{
		//string s;
		cin >> str[i].s;
	}
	vector<int>a;
	int m=0;
	vector<char>b;
	//string stri[100] = { NULL };
	string stri[100];//string不需要显式初始化
	for (int i = 0; i < n; i++)
	{
		a.clear();//先对vector容器进行清空
		b.clear();
		int sum = 0;
		for (int j = 0; j <= 6; j++)//字符串一共7个,所以j是小于等于6或者小于7,别再犯低级错误了!!!
		{
			if (j % 2 == 0)
			{
				m = str[i].s[j] - '0';
				a.push_back(m);
			}
			else {
				b.push_back(str[i].s[j]);
			}	
		}
		//共4*4*4=64种情况,实在列不下去了,就列举了12种
		if (b[0] == '+' && b[1] == '+' && b[2] == '+') {
			sum = a[0] + a[1] + a[2] + a[3];
		}
		if (b[0] == '+' && b[1] == '+' && b[2] == '-') {
			sum = a[0] + a[1] + a[2] -a[3];
		}
		if (b[0] == '+' && b[1] == '+' && b[2] == 'x') {
			sum = a[0] + a[1] + a[2] *a[3];
		}
		if (b[0] == '+' && b[1] == '+' && b[2] == '/') {
			sum = a[0] + a[1] + a[2] / a[3];
		}
		if (b[0] == '+' && b[1] == '-' && b[2] == '+') {
			sum = a[0] + a[1] - a[2] + a[3];
		}
		if (b[0] == '+' && b[1] == '-' && b[2] == '-') {
			sum = a[0] + a[1] - a[2] - a[3];
		}
		if (b[0] == '+' && b[1] == '-' && b[2] == 'x') {
			sum = a[0] + a[1] - a[2] * a[3];
		}
		if (b[0] == '+' && b[1] == '-' && b[2] == '/') {
			sum = a[0] + a[1] - a[2] / a[3];
		}
		if (b[0] == '+' && b[1] == 'x' && b[2] == '+') {
			sum = a[0] + a[1] * a[2] + a[3];
		}
		if (b[0] == '+' && b[1] == 'x' && b[2] == '-') {
			sum = a[0] + a[1] * a[2] - a[3];
		}
		if (b[0] == '+' && b[1] == 'x' && b[2] == 'x') {
			sum = a[0] + a[1] * a[2] * a[3];
		}
		if (b[0] == '+' && b[1] == 'x' && b[2] == '/') {
			sum = a[0] + a[1] * a[2] / a[3];
		}
		if (sum == 24)
		{
			//stri[i] = 'Yes';
			stri[i] = "Yes";
		}
		else {
			//stri[i] = 'No';
			stri[i] = "No";
		}
		
	}
	for (int i = 0; i < n; i++) {
		cout << stri[i] << endl;
	}
	return 0;
}

方法二:中缀表达式直接求值,两个栈,一个存放数值,一个存放符号

思路可以参考之前写过的博客:栈的应用之表达式求值(前缀、中缀、后缀)-CSDN博客

注意:

①循环条件:栈外元素比栈顶元素优先级小或相等+栈不为空,两个条件才能继续循环

②关于报错:back() called on empty deque:应该先检查栈是否为空,再写其他条件

✘while (pri(s[j]) <= pri(top)||optr.empty()==true)
循环条件是:栈外元素比栈顶元素优先级小或相等+栈不为空,两个条件才能继续循环,所以不应该是||,而是&&。
✘while (pri(s[j]) <= pri(optr.top())&&!optr.empty())
后判空,也是错误的。应该先判空!!!    
✔while (!optr.empty()&&pri(s[j]) <= pri(optr.top()))        

③这里栈不清空不影响,因为只要是看运算符的栈,每次循环结束后,这个栈都是空的。

代码:

#include<iostream>
#include<stack>
using namespace std;
int pri(char op) {//设置优先级
	if (op == 'x' || op == '/') {
		return 2;
	}
	else if (op == '+' || op == '-') {
		return 1;
	}
}
int comp(char op, int x, int y) {//计算
	switch (op)
	{
	case '+':return x + y; break;
	case '-':return x - y; break;
	case 'x':return x * y; break;
	case '/':return x / y; break;
	default:break;
	}
}
int main()
{
	int n;
	cin >> n;
	string s;
	stack<int>opnd;//存放数字
	stack<char>optr;//存放符号
	string str[100];//存放结果
	for (int i = 0; i < n; i++)
	{
		cin >> s;
		int res = 0;
		for (int j = 0; j <7; j++)
		{
			if (s[j] > '0' && s[j] <= '9')
			{
				opnd.push(s[j] - '0');
			}
			else {
				if(optr.empty())//栈为空
				{
					optr.push(s[j]);
				}
				else {
					
					if (pri(s[j]) > pri(optr.top())) {
						optr.push(s[j]);
					}
					else {
						//while (pri(s[j]) <= pri(top)||optr.empty()==true)
                        //栈外元素比栈顶元素优先级小或相等+栈不为空,两个条件才继续循环
						//while (pri(s[j]) <= pri(optr.top())&&!optr.empty())
						// 后判空,也是错误的。应该先判空!!!	
						while (!optr.empty()&&pri(s[j]) <= pri(optr.top()))						
						{
							int p = opnd.top();
							opnd.pop();
							int q = opnd.top();
							opnd.pop();
							//注意这里是:次栈顶元素加减乘除栈顶元素!!!
							int result = comp(optr.top(), q, p);
							opnd.push(result);
							optr.pop();							
						}
						optr.push(s[j]);
					}
				}
			}
		}
		//遍历结束后
		while (!optr.empty())
		{
			char top = optr.top();
			int p = opnd.top();
			opnd.pop();
			int q = opnd.top();
			opnd.pop();
			res= comp(top, q, p);
			opnd.push(res);
			optr.pop();
		}

		if (res == 24) {
			str[i] = "Yes";
		}
		else {
			str[i] = "No";
		}
		
	}
	for (int i = 0; i < n; i++) {
		cout << str[i] << endl;
	}
	return 0;
}

方法三:将中缀表达式转换为后缀来计算
注意:

①在使用STL容器涉及循环时,最好应该在每一次循环开始前清空,否则影响下一次循环。

②使用到的两个栈的数据类型是不一样的,注意字符和数字之间的转换。

思路:可参考之前写过的博客栈的应用之表达式求值(前缀、中缀、后缀)-CSDN博客

代码:

#include<iostream>
#include<stack>
#include<vector>
using namespace std;
int pri(char op) {//设置优先级
	if (op == 'x' || op == '/') {
		return 2;
	}
	else if (op == '+' || op == '-') {
		return 1;
	}
}
int comp(char op, int x, int y) {//计算
	switch (op)
	{
	case '+':return x + y; break;
	case '-':return x - y; break;
	case 'x':return x * y; break;
	case '/':return x / y; break;
	default:break;
	}
}
int main()
{
	int n;
	cin >> n;
	string s;
	stack<char>st1;//用来将中缀转换为后缀,存放符号
	stack<int>st2;//用来对后缀求值,存放数字,为int型
	vector<char>v;//用来存放后缀表达式
	string str[100];//存放结果
	for (int i = 0; i < n; i++) {
		cin >> s;
		int result = 0;
		

		//将中缀转换为后缀
		for (int j = 0; j < 7; j++)
		{			
			if (s[j] > '0' && s[j] <= '9') {
				v.push_back(s[j]);
			}
			else {
				if (st1.empty()) {
					st1.push(s[j]);
				}
				else {
					if (pri(s[j]) > pri(st1.top())) {
						st1.push(s[j]);
					}
					else {
						while (!st1.empty() && (pri(s[j]) <= pri(st1.top())))
						{
							v.push_back(st1.top());
							st1.pop();
						}
						st1.push(s[j]);
					}
				}
			}
		}
		//遍历结束后
		while (!st1.empty()) {
			v.push_back(st1.top());
			st1.pop();
		}
		//对后缀求值
		for (vector<char>::iterator it = v.begin(); it != v.end(); it++)
		{
			if (*it > '0' && *it <= '9')
			{
				int m = *it - '0';
				st2.push(m);
			}
			else {
				int p = st2.top() ;
				st2.pop();
				int q = st2.top();
				st2.pop();
				result = comp(*it, q, p);
				//char c = result + '0';
				st2.push(result);//注意这里要加‘0’
			}
		}
		if (result == 24) {
			str[i] = "Yes";
		}
		else {
			str[i] = "No";
		}
		while(!st2.empty())
		{
			st2.pop();
		}
		v.clear();
	}
	for (int i = 0; i < n; i++) {
		cout << str[i] << endl;
	}
	return 0;
}

三、总结

这应该是我写的最长时间的题目了,其实从上周二就开始写这道题,关键第一次看这题的时候,还觉得它很简单,以为不就是算术运算吗。真是啪啪打脸。根本原因还是自己忘了之前学过的栈的应用之表达式求值,它是做本题的最好方法。这次,又把它重新学了一下,感觉有了更深刻的体会和新的认识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2138685.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

台风,也称为热带气旋,是一种在热带海洋上形成的强烈风暴系统。台风的形成需要满足以下几个条件:

台风&#xff0c;也称为热带气旋&#xff0c;是一种在热带海洋上形成的强烈风暴系统。台风的形成需要满足以下几个条件&#xff1a; 1. **温暖的海水**&#xff1a;台风通常在海面温度至少达到26.5C&#xff08;79.7F&#xff09;的海域形成&#xff0c;因为温暖的海水能够提供…

八股(8)——Spring,SpringBoot

八股&#xff08;8&#xff09;——Spring&#xff0c;SpringBoot 基础1.Spring 是什么&#xff1f;特性&#xff1f;有哪些模块&#xff1f;Spring 有哪些特性呢&#xff1f; 2.Spring 有哪些模块呢&#xff1f;3.Spring 有哪些常用注解呢&#xff1f;Web 开发方面有哪些注解呢…

利用模糊综合评价法进行数值评分计算——算法过程

1、‌模糊综合评价法概述 ‌模糊综合评价法是一种基于模糊数学的综合评价方法&#xff0c;它通过模糊数学的隶属度理论将定性评价转化为定量评价&#xff0c;适用于解决复杂、难以量化的问题。该方法具有结果清晰、系统性强的特点&#xff0c;能够处理多种因素制约下的综合评价…

热门数据恢复软件大盘点

现在大家的数据都喜欢存放在一些电子设备里保存吧。这样既方便存放&#xff0c;也方便我们查找。但是这些设备可能因为病毒、误删除等原因造成数据的丢失。这篇文章我将介绍几款类似易我数据恢复软件的数据恢复工具&#xff0c;减少为数据丢失给我们造成损失。 1.FOXIT数据恢复…

vue国际化

前言 现在的大公司都走国际化路线&#xff0c;我们应用程序也不例外。今天就在 Vue3 项目中整一个比较简单的国际化 背景 之前搞国际化的时候&#xff0c;也搜索了很多帖子&#xff0c;但是没有一个可以完整的实现。今天有空搞了一版&#xff0c;大家有什么问题欢迎留言探讨…

Java设计模式—面向对象设计原则(五) ----->迪米特法则(DP) (完整详解,附有代码+案例)

文章目录 3.5 迪米特法则(DP)3.5.1 概述3.5.2 案例 3.5 迪米特法则(DP) 迪米特法则&#xff1a;Demeter Principle&#xff0c;简称DP 3.5.1 概述 只和你的直接朋友交谈&#xff0c;不跟“陌生人”说话&#xff08;Talk only to your immediate friends and not to stranger…

【CSS in Depth 2 精译_031】5.3 Grid 网格布局的两种替代语法

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

Linux服务器配合Xshell+Tensorboard实现深度学习训练过程可视化

问题背景&#xff1a; 在深度学习领域&#xff0c;监控模型的训练过程是非常重要的。TensorBoard 是 TensorFlow 提供的一个可视化工具&#xff0c;可以帮助我们直观地理解模型的训练和验证过程。我们一般在 Windows 系统只需要在自己的浏览器输入localhost:6006就可以观察训练…

[Linux]:进程间通信(上)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;Linux学习 贝蒂的主页&#xff1a;Betty’s blog 1. 进程间通信介绍 1.1 进程间通信的概念 进程间通信简称IPC&#xff08;In…

[通信原理]绪论1:信号 × 通信系统

1、消息、信号与信息 消息&#xff1a; 通信系统要传输的对象&#xff0c;是具体的、物理上存在的东西。也是信息的载体。形式多种&#xff1a; 连续消息&#xff1a;语音、温度、活动图片.离散消息&#xff1a;数据、符号、文字. 信息&#xff1a; 消息中所蕴含的内容&…

MySQL练手题--公司和部门平均工资比较(困难)

一、准备工作 Create table If Not Exists Salary (id int, employee_id int, amount int, pay_date date); Create table If Not Exists Employee (employee_id int, department_id int); Truncate table Salary; insert into Salary (id, employee_id, amount, pay_date) va…

ESP8266+httpServer+GET+POST实现网页验证密码

1. 代码 #include "esp_http_server.h" #include "esp_log.h" #include "web_server.h"// 辅助宏&#xff0c;用于计算两个数中的较小值 #define MIN(a, b) ((a) < (b) ? (a) : (b))static const char *TAG "wifi web_server";c…

游戏算法专题之PRD算法:听说你想凭运气抽中荣耀水晶?

PRD算法全称Pseudo-Random Distribution。是概率分布中的一种常见算法&#xff0c;在游戏开发领域中很常用。 PRD用于控制随机事件的触发概率&#xff0c;使其表现得更加符合预期&#xff0c;相比于传统得随机数生成&#xff0c;PRD算法可以平滑得控制随机事件的触发次数&…

cJSON-轻量级解析模块、字符串的神——编织STM32C8T6与阿里云信息传递的纽带

编写方向&#xff1a;本人就不泛泛的编写一篇什么一文学会cJSON了&#xff0c;没什么突出点&#xff0c;也就我水水字数&#xff0c;你们看来看去也不懂&#xff0c;本人是从上阿里云传信息接触的cJSON的&#xff0c;我就此写一篇针对性的文章&#xff0c;希望对大家有用&#…

通信工程学习:什么是UNI用户网络接口

UNI&#xff1a;用户网络接口 UNI&#xff08;User Network Interface&#xff09;用户网络接口&#xff0c;是网络通信中的一个重要概念&#xff0c;它连接了用户设备与智能光网络或其他类型的网络。以下是关于UNI用户网络接口的详细解释&#xff1a; 一、定义与功能 定义&am…

VSCode C++(Code Runner)+ OpenSSL开发环境搭建

本章教程,主要介绍在VSCode中配置OpenSSL环境。 一、安装 OpenSSL 首先,我们需要安装OpenSSL,并配置OpenSSL系统环境变量。 1、下载OpenSSL 下载地址:https://slproweb.com/products/Win32OpenSSL.html 如果下载慢可以通过下方网盘进行下载: 通过网盘分享的文件:Win64Op…

Geneformer AI 模型,有限数据也能解锁基因网络

目录 类似于 BERT 的单单元数据参考模型 NVIDIA Clara 工具组合用于药物研发 用于疾病建模的基础 AI 模型 Geneformer 是最近推出的 和功能强大的 AI 模型&#xff0c;可以通过从大量单细胞转录组数据中进行迁移学习来学习基因网络动力学和相互作用。借助此工具&#xff0c;…

ICPC网络赛 以及ACM训练总结

一、训练反思 关于我自己暑假期间训练的反思&#xff0c;我承认无论是因为什么原因&#xff0c;我自己浪费我整整一个暑假的时间&#xff0c;暑假期间正是我们集训的关键时期&#xff0c;这期间没有任何的事情来打扰我们学习&#xff0c;而我却熬夜&#xff0c;白天训练懈怠&a…

C++类与对象(二)超详细

目录 1.类的6个默认成员函数 2..构造函数 2.1概念 2.2 特征 3.析构函数 3.1 概念 3.2 特性 4.拷贝构造函数 4.1 概念 4.2 特征 5.赋值运算符重载函数 5.1 运算符重载&#xff08;是否重载这个运算符是看这个运算符对这个类是否有意义&#xff09; 5.2 赋值运算符重…

嵌入式单片机程序运行基本机理

1. 程序各种要素说明 大家好,今天用一个最简单的程序跟大家讲清楚程序的构成。 1.1. 概述 硬件首先要知道硬件的组成。 在前面章节我们说过,芯片包含Flash和RAM。 他们虽然不是相同的东西,但是都属于同一个地址空间,32位芯片的地址空间大小是4G。 比如ST32,FLASH通常从…