【360秋招笔试】编程题第二题:修改Web(C++的AC解法)

news/2024/7/23 10:13:35 标签: 前端, c++, 开发语言

题目

先看样例:

6
16=1+2*3
7*8*9=54
1+1=1+22
4*6=22+2
15+7=1+2
11+1=1+5

n表示输入n行数据,下面每一行数据表示一个等式。如果能满足 在等式中添加任意一个数字 使得等式两边成立,则输出Yes,否则输出No。如果等式本来就相等,也输出Yes。

符号只有+,*和=。都是正整数。

想测试自己的拆分或计算是否正确,可以只使用一个样例:

1
16=1+2*3

思路

过程略微复杂的模拟题。

想要进行计算,需要将等式(字符串)拆分为数字和字符。计算过程类似于逆波兰表达式,用栈来实现。至于是否存在添加一个数字使得等式成立,我们可以枚举

本题解C++。(这种数据输入感觉用C++会方便,如果用JS需要异步??360的编程题竟然没有给输入的模板,直接ACM模式

输入字符串,得到数字和字符的函数:其中cntNum、cntCh等是指针,用来记录一共拆分出了多少数。

void stringTo(string a){
    int temp=0;
    for(int i=0;a[i];i++){
        if(a[i]>='0'&&a[i]<='9'){
            temp*=10;
            temp+=a[i]-'0';
        }else{
            ch[cntCh]=a[i];
            cntCh++;
            num[cntNum]=temp;
            cntNum++;temp=0;
        }
    }
    num[cntNum]=temp;
    cntNum++;temp=0;
}

对等号=左右两边的数字进行计算,思想是逆波兰表达式

这里的参数left、right表示计算数组中[left,right]的答案。这样,只需要改变参数就可以分别计算等号左边和等号右边。

注意,数字的数量会比符号多1,因此可以先把第一个数字压入栈。

//计算左右两边的大小 
//左 1,indexx
//右 indexx+1,end 
int cal(int left,int right){
	if(left==right) return num[left];
	
	stack<int>numm;stack<char>chh;
	numm.push(num[left]);
//	数字 
	for(int i=left+1;i<=right;i++){
		//对应的操作符是i-1的下标 
		char op=ch[i-1];
		//优先级高 
		if(op=='*'){
			int qian=numm.top();numm.pop();
			int hou=num[i];
			int temp=qian*hou;
			numm.push(temp);
		}
		else{
			numm.push(num[i]);
			chh.push(ch[i-1]);
		}
	}
	
//	计算加减
	
	while(chh.size()){
		char op=chh.top();chh.pop();
		int hou=numm.top();numm.pop();
		int qian=numm.top();numm.pop();
		int temp=qian+hou;
		numm.push(temp);
	} 
	return numm.top();
}

枚举在字符串中每一个位置都插入一个数字并计算:

for(int i=0;a[i];i++){
	c.clear();
	b+=a[i];
	c+=b;
	for(int j=0;j<=9;j++){
		c+=char('0'+j);
		c+=a.substr(i+1);
		if(solve(c)) {
			flag=1;break;
		}
		c.clear();c+=b;
	}
	if(flag) break;
}

总体的过程:将字符串转换为数字和符号、计算。这个过程可以封装一下:

bool solve(string a){
	clearr();
	stringTo(a);
	findEqual();
	l=cal(0,indexx);
	r=cal(indexx+1,cntNum-1);
	if(l==r) return true;
	else return false;
}

总体代码(AC)

#include<bits/stdc++.h>
using namespace std;
int t;string a;
int num[5000];
char ch[5000];
int cntNum=0,cntCh=0;
int indexx;//=的下标 
int l,r;
void clearr(){
	cntNum=0,cntCh=0;
}
void stringTo(string a){
    int temp=0;
    for(int i=0;a[i];i++){
        if(a[i]>='0'&&a[i]<='9'){
            temp*=10;
            temp+=a[i]-'0';
        }else{
            ch[cntCh]=a[i];
            cntCh++;
            num[cntNum]=temp;
            cntNum++;temp=0;
        }
    }
    num[cntNum]=temp;
    cntNum++;temp=0;
}
//找到=的下标index 对应num的下标,index及其之前的都是=号左边的 
void findEqual(){
	for(int i=0;i<cntCh;i++){
		if(ch[i]=='='){
			indexx=i;break;
		}
	} 
}
//计算左右两边的大小 
//左 1,indexx
//右 indexx+1,end 
int cal(int left,int right){
	if(left==right) return num[left];
	
	stack<int>numm;stack<char>chh;
	numm.push(num[left]);
//	数字 
	for(int i=left+1;i<=right;i++){
		//对应的操作符是i-1的下标 
		char op=ch[i-1];
		//优先级高 
		if(op=='*'){
			int qian=numm.top();numm.pop();
			int hou=num[i];
			int temp=qian*hou;
			numm.push(temp);
		}
		else{
			numm.push(num[i]);
			chh.push(ch[i-1]);
		}
	}
	
//	计算加减
	
	while(chh.size()){
		char op=chh.top();chh.pop();
		int hou=numm.top();numm.pop();
		int qian=numm.top();numm.pop();
		int temp=qian+hou;
		numm.push(temp);
	} 
	return numm.top();
}

bool solve(string a){
	clearr();
	stringTo(a);
	findEqual();
	l=cal(0,indexx);
	r=cal(indexx+1,cntNum-1);
	if(l==r) return true;
	else return false;
}

int main(){
    cin>>t;
    while(t--){
    	clearr();l=0,r=0;
        cin>>a;
        stringTo(a);
        
//        找= index
		findEqual();
		l=cal(0,indexx);
		r=cal(indexx+1,cntNum-1);
		
		if(l==r) {
			cout<<"Yes"<<endl;continue;
		}
		
		string b,c;int flag=0;
		//在最前面加
		for(int i=0;i<=9;i++){
			c.clear();
			c+=char('0'+i);
			c+=a;
			if(solve(c)) {
				flag=1;break;
			}
		}
		if(flag) {
			cout<<"Yes"<<endl;continue;
		}
		
		b.clear();c.clear();
		 
		for(int i=0;a[i];i++){
			c.clear();
			b+=a[i];
			c+=b;
			for(int j=0;j<=9;j++){
				c+=char('0'+j);
				c+=a.substr(i+1);
				if(solve(c)) {
					flag=1;break;
				}
				c.clear();c+=b;
			}
			if(flag) break;
		}
		if(flag) {
			cout<<"Yes"<<endl;continue;
		}
		else cout<<"No"<<endl;    
    }
    return 0;
}

不重要心得

很典型且要素很多的模拟题,字符串的计算+逆波兰表达式+枚举。写了70多分钟!
输入的数据范围并不大,所以枚举可以实现。不知道有没有更好的写法。
代码写的乱乱的,也不精简,等有空的时候重新写一下。

另外:我是前端啊!但是看到编程题没有给异步输入数据的模板的时候傻眼了。。这咋做。。被迫捡起用C++打题的记忆了,不然就寄了。


http://www.niftyadmin.cn/n/5046325.html

相关文章

mysql workbench常用操作

1、No database selected Select the default DB to be used by double-clicking its name in the SCHEMAS list in the sidebar 方法一&#xff1a;双击你要使用的库 方法二&#xff1a;USE 数据库名 2、复制表名&#xff0c;字段名 3、保存链接

Compositional Minimax Optimization学习之路

梯度 最优化理论 最优化基础---基本概念&#xff1a;凸优化、梯度、Jacobi矩阵、Hessian矩阵_哔哩哔哩_bilibili 从图像来看&#xff1a;存在两点连线上的点不在集合内 定义 ax1(1-a)x2 其实就是两点连线上的点 可用 与函数围成的面积 和 与坐标轴围成的面积 角度理解凸函数…

Java————网络编程

一 、网络编程基础 1. 为什么需要网络编程 用户在浏览器中&#xff0c;打开在线视频网站&#xff0c; 如优酷看视频&#xff0c;实质是通过网络&#xff0c; 获取到网络上的一个视频资源。 与本地打开视频文件类似&#xff0c;只是视频文件这个资源的来源是网络。 相比本地资…

编程世界里的爱情观:Python 程序员的爱情难题

“问世间情为何物&#xff0c;直教人生死相许。”爱情是世间最美好的事物之一&#xff0c;然而&#xff0c;当爱变得沉重&#xff0c;当喜欢的那个人开始让你觉得痛苦&#xff0c;你是否会选择放手&#xff1f; Python 编程助力职业发展&#xff1a;掌握行业趋势&#xff0c;实…

C++ list容器的实现及讲解

所需要的基础知识 对C类的基本了解 默认构造函数 操作符重载 this指针 引用 模板等知识具有一定的了解&#xff0c;阅读该文章会很轻松。 链表节点 template<class T>struct list_node{T _data;list_node<T>* _next;list_node<T>* _prev;list_node(const T&…

【整理】text2kgbench: 语言模型根据本体生成知识图谱的能力

概述 该论文的研究背景是大型语言模型&#xff08;LLM&#xff09;和基于本体的知识图谱&#xff08;KG&#xff09;在自然语言处理&#xff08;NLP&#xff09;任务中的性能提升。 过去的方法存在一些问题&#xff0c;该论文提出的方法通过从文本中生成KG并遵循给定的本体&…

2023-09-22力扣每日一题

链接&#xff1a; 2591. 将钱分给最多的儿童 题意 把钱全部发给人&#xff0c;每个人都必须有钱&#xff0c;不能有人有4元 让最多的人拿到8元 解&#xff1a; 简单题&#xff0c;贪心查缺补漏 实际代码&#xff1a; int distMoney(int money, int children) {money-ch…

pytest框架运行时的参数,以及多线程分布式运行用例、运行指定模块用例

一、运行时的参数 在上一篇博客中写了pytest最为核心的运行时前后置如何设置&#xff0c;细心的朋友可能也会发现其实我们当时就加过运行时的参数-vs。 pytest.main([‘-s’])&#xff1a;能打印出调试信息&#xff0c;print()或者日志都可以直接打印在控制台上。 pytest.ma…