化学方程式小程序

brief introduction

相信大家上中学时都会被化学方程式折腾得死去活来,尤其是配平,怎么也算不对数字。于是我写出了这款近200行的自动配平程序,这是不是你们黑暗化学中的一丝光亮呢?

usage

正常化学式输入,每一种物质之间空一格,反应物/生成物输入完后空一格并打一个‘-’(不带单引号)。一般情况下输入完后可以立刻出结果。需要保证系数在 [ 1 , 50 ] [1,50] [1,50] 之间。

code
#include<bits/stdc++.h>
using namespace std;
string s[20], t[20];
int l[20][25], r[20][25], mid[20][25], ans[25], suml[25], sumr[25], le[25], le2[25], suml2[25];
bool vis[25], flag;
map<string, int> fy, sc, ele;
vector<int> to[25];
int a = 1, b = 1, tot, cnt, ok, o;
void dfs2(int step) {
	if(vis[step]) dfs2(step+1);
	if(step == b+1) {
		for(int i = 1;i <= tot;++i) 
			if(suml2[i]) return;
		for(int i = 1;i <= a;++i) {
			if(ans[i]!=1) printf("%d", ans[i]);
			cout << s[i];
			if(i != a) printf("+");
		}
		printf("==");
		for(int i = 1;i <= b;++i) {
			if(ans[a+i]!=1) printf("%d", ans[a+i]);
			cout << t[i];
			if(i != b) printf("+");
		}
		exit(0);
	}
	while(o) {
		flag = false;
		for(int i = 1;i <= tot;++i)
			if(le2[i] == 1) {
				int pos = to[i].size()-1;
				while(pos>=0 && to[i][pos]>=step && vis[to[i][pos]]) --pos;
				pos = to[i][pos];
				int x = suml2[i]/r[pos][i];
				if(vis[pos]) continue;
				flag = true;
				--o;
				if(suml2[i]%r[pos][i] || !suml2[i]) return;
				ans[a+pos] = x;
				vis[pos] = true;
				for(int j = 1;j <= tot;++j) {
					if(r[pos][j]) suml2[j] -= r[pos][j]*x, --le2[j];
					if(le2[j] == 1) ++o;
				}
				for(int j = 1;j <= tot;++j) 
					if(suml2[j] < 0) return;
			}
		if(!flag) break;
	}
	if(vis[step]) dfs2(step+1);
	else {
		int mn = 100;
		for(int i = 1;i <= tot;++i) mn = min(mn, suml2[i]/r[step][i]);
		for(int i = 1;i <= mn;++i) {
			ans[a+step] = i;
			bool fl = false;
			for(int j = 1;j <= tot;++j) {
				if(r[step][j]) {
					suml2[j] -= r[step][j]*i, --le2[j];
					if(le2[j]==1 && !fl) ++o, fl = true;
				}
			}
			dfs2(step+1);
			for(int j = 1;j <= tot;++j) 
				if(r[step][j]) {
					suml2[j] += r[step][j]*i, ++le2[j];
					if(le2[j]==1 && !fl) --o;
				}
		}	
	}
	return;
}
void dfs(int step) {
	if(step == a+1) {
		for(int i = 1;i <= tot;++i) suml2[i] = 0, suml[i] = 0, sumr[i] = 0, le2[i] = le[i];
		for(int i = 1;i <= b;++i) vis[i] = false;
		o = ok;
		for(int i = 1;i <= tot;++i)
			for(int j = 1;j <= a;++j)
				suml[i] += l[j][i]*ans[j], suml2[i] += l[j][i]*ans[j];
		dfs2(1);
		return;
	}
	for(int i = 1;i <= 50;++i) {
		ans[step] = i;
		dfs(step+1);
	}
}
int main () {
	while(cin >> s[a++] && s[a-1][0] != '-'); --a, --a;
	while(cin >> t[b++] && t[b-1][0] != '-'); --b, --b;
	for(int i = 1;i <= a;++i) {
		for(int j = 0;j < s[i].size();++j) {
			string str; str.clear();
			if(isupper(s[i][j])) {
				str += s[i][j];
				if(islower(s[i][j+1])) ++j, str += s[i][j];
				fy[str] = 1;
			}
		}
	}
	for(int i = 1;i <= b;++i) {
		for(int j = 0;j < t[i].size();++j) {
			string str; str.clear();
			if(isupper(t[i][j])) {
				str += t[i][j];
				if(islower(t[i][j+1])) ++j, str += t[i][j];
				if(fy[str] == 0) printf("Error!"), exit(0);
				sc[str] = 1;
			}
		}
	}
	for(auto it = fy.begin(); it != fy.end();++it) {
		ele.insert({it->first, ++tot});
		if(!sc[it->first]) printf("Error!"), exit(0);
	}
	for(int i = 1; i <= a;++i) {
		for(int j = 0;j < s[i].size();++j) {
			string str; str.clear();
			if(s[i][j] == '(') {
				++j; cnt = 0;
				while(s[i][j] != ')') {
					str.clear();
					str += s[i][j];
					if(islower(s[i][j+1])) ++j, str += s[i][j];
					++j;
					int num = 1;
					if(!isdigit(s[i][j])) mid[++cnt][ele[str]] = num;
					else {
						num = s[i][j]-'0';
						if(isdigit(s[i][j+1])) ++j, num = 10*num+s[i][j]-'0';
						++j; mid[++cnt][ele[str]] = num;
					}
				}
				++j;
				int num = s[i][j]-'0';
				if(isdigit(s[i][j+1])) ++j, num = 10*num+s[i][j]-'0';
				for(int j = 1;j <= cnt;++j)
					for(int k = 1;k <= tot;++k)
						l[i][k] += mid[j][k]*num;
			}
			else {
				str += s[i][j];
				if(islower(s[i][j+1])) ++j, str += s[i][j];
				int num = 1;
				if(!isdigit(s[i][j+1])) {l[i][ele[str]] += num; continue;}
				++j, num = s[i][j]-'0';
				if(!isdigit(s[i][j+1])) {l[i][ele[str]] += num; continue;}
				++j, num = 10*num+s[i][j]-'0';
				l[i][ele[str]] = num;
			}
		}
	}
	for(int i = 1; i <= b;++i) {
		for(int j = 0;j < t[i].size();++j) {
			string str; str.clear();
			if(t[i][j] == '(') {
				++j; cnt = 0;
				while(t[i][j] != ')') {
					str.clear();
					str += t[i][j];
					if(islower(t[i][j+1])) ++j, str += t[i][j];
					++j;
					int num = 1;
					if(!isdigit(t[i][j])) mid[++cnt][ele[str]] = num;
					else {
						num = t[i][j]-'0';
						if(isdigit(t[i][j+1])) ++j, num = 10*num+t[i][j]-'0';
						++j; mid[++cnt][ele[str]] = num;
					}
					to[ele[str]].push_back(i), ++le[ele[str]];
				}
				++j;
				int num = t[i][j]-'0';
				if(isdigit(t[i][j+1])) ++j, num = 10*num+t[i][j]-'0';
				for(int j = 1;j <= cnt;++j)
					for(int k = 1;k <= tot;++k)
						r[i][k] += mid[j][k]*num;
			}
			else {
				str += t[i][j];
				if(islower(t[i][j+1])) ++j, str += t[i][j];
				to[ele[str]].push_back(i), ++le[ele[str]];
				int num = 1;
				if(!isdigit(t[i][j+1])) {r[i][ele[str]] += num; continue;}
				++j, num = t[i][j]-'0';
				if(!isdigit(t[i][j+1])) {r[i][ele[str]] += num; continue;}
				++j, num = 10*num+t[i][j]-'0';
				r[i][ele[str]] = num;
			}
		}
	}
	for(int i = 1;i <= tot;++i)
		if(le[i] == 1) ++ok;
	dfs(1);
    return 0;
}
demonstration

在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Vue】elementUI表格,导出Excel

系列文章 【Vue】vue增加导航标签 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/134965353 【Vue】Element开发笔记 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/133947977 【Vue】vue&#xff0c;在Windows IIS平台…

windows下redis 设置开机自启动

1&#xff0c;在redis的目录下执行&#xff08;执行后就作为windows服务了&#xff09; redis-server --service-install redis.windows.conf 2&#xff0c;安装好后需要手动启动redis redis-server --service-start 3&#xff0c;停止服务 redis-server --service-stop

人工智能与大数据的紧密联系

随着科技的飞速发展&#xff0c;人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;和大数据&#xff08;Big Data&#xff09;已成为当今社会的热门话题。人工智能在许多领域的应用越来越广泛&#xff0c;而大数据则提供了支持和驱动AI技术的巨大资源。本…

2023-12-16:用go语言,给定整数数组arr,求删除任一元素后, 新数组中长度为k的子数组累加和的最大值。 来自字节。

2023-12-16&#xff1a;用go语言&#xff0c;给定整数数组arr&#xff0c;求删除任一元素后&#xff0c; 新数组中长度为k的子数组累加和的最大值。 来自字节。 答案2023-12-16&#xff1a; 来自左程云。 灵捷3.5 大体步骤如下&#xff1a; 算法 maxSum1 分析&#xff1…

QT----第三天,Visio stdio自定义封装控件,鼠标事件,定时器,事件分发器过滤器,绘图事件

目录 第三天1 自定义控件封装2 QT鼠标事件3 定时器4 event事件分发器5 事件过滤器6 绘图事件Qpainter 源码&#xff1a;CPP学习代码 第三天 1 自定义控件封装 新建一个QT widgetclass&#xff0c;同时生成ui,h,cpp文件 在smallWidget.ui里添加上你想要的控件并调试大小 回到…

day01-报表技术POI

前言 报表[forms for reporting to the higher organizations]&#xff0c;就是向上级报告情况的表格。简单的说&#xff1a;报表就是用表格、图表等格式来动态显示数据&#xff0c;可以用公式表示为&#xff1a;“报表 多样的格式 动态的数据”。 1、开发环境搭建 功能说…

【Python动漫系列】哆啦A梦(完整代码)

文章目录 哆啦A梦环境需求完整代码程序分析系列文章哆啦A梦 《哆啦A梦》是由日本漫画家藤子F不二雄创作的一部科幻搞笑漫画,故事中的主角是一只来自未来的机器猫——哆啦A梦。该作品于1969年开始连载,至今已经持续了50多年,成为了日本乃至全球最受欢迎的漫画之一。 故事发…

c++_01_名字空间_复合类型_缺省参数_哑元函数

0 前言 C和C一样&#xff0c;都属于编译型语言 C和C一样&#xff0c;都属于强类型语言 C对C完全兼容&#xff0c;并提供更多面向对象的特性&#xff1a;语言风格更加简洁&#xff0c;类型检查更加严格 1 名字空间 namespace WHY&#xff1f;划分更精细的逻辑单元(逻辑空间)&…

AC843. n皇后问题--60

我们只需要把蓝色的往上移动就行了 if(!col[i][j]&&!dg[ui]&&!udg[])//1y&#xff08;i&#xff09;向下&#xff0c;x&#xff08;u&#xff09;向右为正。yxb的by-x一定>0,y-xb的bxy可能>0,这个不考虑&#xff0c;只看-bxy.

Python-数据分析可视化实例图

Python-数据分析可视化实例图 一&#xff1a;3D纹理图 运行效果图&#xff1a; Python代码&#xff1a; import math from typing import Unionimport pyecharts.options as opts from pyecharts.charts import Surface3Ddef float_range(start: int, end: int, step: Union[…

翻译: 工作使用ChatGPT的例子 Day-to-day usage of web UI LLMs

本周&#xff0c;我们将首先探讨生成型AI在商业中的作用&#xff0c;然后是其对社会的影响&#xff0c;例如对就业的影响。我们将从探讨如何在日常工作中使用网络用户界面访问生成型AI开始&#xff0c;然后再看看如何系统地分析一个企业&#xff0c;以识别使用生成型AI增强或自…

Linux面试题精选:提升你的面试准备

大家有关于JavaScript知识点不知道可以去 &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&#xff1a;ajax知识点 &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 学习…

商用机器人,不好用是原罪

热潮褪去后&#xff0c;所有的问题都汇总成一个词&#xff0c;不好用。 从炙手可热到“大玩具” 一款产品好用与否&#xff0c;更多时候人们不会关心它先进的技术、工艺、用料&#xff0c;也不会考虑所谓的潮流趋势或前景&#xff0c;只会用最朴素的直观感受告诉你&#xff0…

LabVIEW开发地铁运行安全监控系统

LabVIEW开发地铁运行安全监控系统 最近昌平线发生的故障事件引起了广泛关注&#xff0c;暴露了现有地铁运行监控系统在应对突发情况方面的不足。为了提高地铁系统的运行安全性&#xff0c;并防止类似事件再次发生&#xff0c;提出了一套全面的地铁运行安全监控系统方案。此方案…

NAT——网络地址转换

目录 一、概念 二、NAT的分类 1.静态NAT 1.1 静态NAT的配置 1.2 利用eNSP小实验加强对静态NAT的理解 2、动态NAT 三、NAPT——端口映射 四、Easy IP 使用一个公网地址可以让所有人都上公网 一、概念 随着Internet的发展和网络应用的增多&#xff0c;IPv4地址枯竭已经成为…

【C语言(十)】

字符函数和字符串函数 一、字符分类函数 C语言中有⼀系列的函数是专门做字符分类的&#xff0c;也就是⼀个字符是属于什么类型的字符的。这些函数的使用都需要包含⼀个头文件是 ctype.h 这些函数的使用方法非常类似&#xff0c;我们就讲解⼀个函数的事情&#xff0c;其他的非…

鸿蒙4.0开发 - DevEco Studio如何使用Previewer窗口预览器报错

DevEco Studio预览器概况在HarmonyOS应用开发过程中&#xff0c;通过使用预览器&#xff0c;可以查看应用的UI效果&#xff0c;方便开发者实时查看应用的运行效果&#xff0c;随时调整代码。 1.正常启动 打开预览器的位置在DevEco Studio编辑界面的右上角部分&#xff0c;竖排…

MySQL低版本中:字符串中的数字、英文字符、汉字提取

我们如何提醒一个字段中的汉字和数字呢 高版本指mysql8.0以上 使用sql语句 SELECT REGEXP_REPLACE(column_name, [^\\p{Han}], ) AS chinese_characters FROM table_name;其中 column_name指名称列&#xff0c;table_name是表名 2.低版本使用 需要新建函数 DELIMITER $$DR…

ChatGPT4 Excel 高级复杂函数案例实践

案例需求: 需求中需要判断多个条件进行操作。 可以让ChatGPT来实现这样的操作。 Prompt:有一个表格B2单元格为入职日期,C2单元格为员工等级(A,B,C),D2单元格为满意度分数(1,2,3,4,5)请给入职一年以上,员工等级为A级并且满意度在3分以上的人发4000元奖金,给入…

《打造第二大脑》—如何构建高效的笔记系统

最近看了一本书&#xff0c;因为我也用Obsidian来记笔记&#xff0c;&#xff08;Obsidian之前有介绍过Obsidian使用教程&#xff08;如何构建你的个人知识库&#xff0c;第二大脑&#xff09;&#xff09;看完这本书后发现里面给的方法跟Obsidian很契合&#xff0c;所以就整理…