CCF-CSP 201912-3化学方程式

本文介绍了一个用于解析和验证化学方程式的C++程序,该程序能够处理复杂的化学反应表达式,包括分子式、离子式以及化学计量数。通过读取输入的化学方程式,程序可以判断方程式是否符合质量守恒定律,即反应物和生成物的原子数量是否相等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CCF-CSP 201912-3化学方程式

满分代码:

#include <bits/stdc++.h>
#define FOR(i,s,t) for(int i=(s);i<=(t);i++)
#define ROF(i,s,t) for(int i=(s);i>=(t);i--)
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define fi first
#define se second
#define endl '\n'
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn = 1e3 + 6;
const ll mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int readInt(){
    int x=0;
    bool sign=false;
    char c=getchar();
    while(!isdigit(c)){
        sign=c=='-';
        c=getchar();
    }
    while(isdigit(c)){
        x=x*10+c-'0';
        c=getchar();
    }
    return sign?-x:x;
}
ll readLong(){
    ll x=0;
    bool sign=false;
    char c=getchar();
    while(!isdigit(c)){
        sign=c=='-';
        c=getchar();
    }
    while(isdigit(c)){
        x=x*10+c-'0';
        c=getchar();
    }
    return sign?-x:x;
}
string readString(){
    string s;
    char c=getchar();
    while(isspace(c)){
        c=getchar();
    }
    while(!isspace(c)){
        s+=c;
        c=getchar();
    }
    return s;
}

int n, e;
string equation;
string lstr, rstr;
vector<string> lfml, rfml;
vector<int> lnum, rnum;
map<string, int> lcnt, rcnt;
int main() {
	int T = readInt();
	while (T--){
		equation = readString();
		e = equation.find('=');
		//cout << e << endl;
		lstr = equation.substr(0, e);
		rstr = equation.substr(e + 1);		
		int fst = 0, plus = 0;
		lfml.clear();
		rfml.clear();
		lnum.clear();
		rnum.clear();
		lcnt.clear();
		rcnt.clear();
		plus = lstr.find('+');
		while (plus != -1){
			string sub = lstr.substr(0, plus);
			lfml.push_back(sub);
			lstr = lstr.substr(plus + 1);
			plus = lstr.find('+');
		}
		
		if (lstr != "") lfml.push_back(lstr);
		//for (auto sub : lfml) cout << sub << " ";
		
		plus = rstr.find('+');
		while (plus != -1){
			string sub = rstr.substr(0, plus);
			rfml.push_back(sub);
			rstr = rstr.substr(plus + 1);
			plus = rstr.find('+');
		}
		if (rstr != "") rfml.push_back(rstr);
		
		/*for (auto sub : rfml) cout << sub << " ";
		cout << endl;*/
		
		for (auto sub : lfml){
			int number = 0;
			for (auto x : sub){
				if (x >= '0' && x <= '9'){
					number = number * 10 + x - '0';
				}
				else break;
			}
			if (number == 0) number = 1;
			lnum.push_back(number);
		}
		
		for (auto sub : rfml){
			int number = 0;
			for (auto x : sub){
				if (x >= '0' && x <= '9'){
					number = number * 10 + x - '0';
				}
				else break;
			}
			if (number == 0) number = 1;
			rnum.push_back(number);
		}
		
		for (int kk = 0; kk < lfml.size(); kk++){
			int number = lnum[kk];
			string sub = lfml[kk];
			vector <string> term;
			int i = 0;
			for (i = 0; i < sub.size();i++){
				if (sub[i] >= '0' && sub[i] <= '9'){continue;}
				else break;
			}
			for (; i < sub.size(); i++){
				
				string element ="";
				element += sub[i];
				if (sub[i] == '(') {term.push_back("(");}
				else if (sub[i] >= 'A' && sub[i] <= 'Z'){
					if (sub[i + 1] >= 'a' && sub[i + 1] <= 'z'){
						element += sub[i+1];
						i++;
					}
					term.push_back(element);
				}
				else if (sub[i] == ')'){term.push_back(")");}
				else if (sub[i] >= '0' && sub[i] <= '9'){
					string mm = "";
					for (;i < sub.size();i++){
						if (sub[i] >= '0' && sub[i] <= '9'){
							mm = mm + sub[i];
						}
						else {
							break;
						}
					}
					i--;
					term.push_back(mm);
				}
			}
			stack <pair<string, int>> stk;
			vector <int> w(term.size());
			vector <int> termnum(term.size());
			for (int i = 0; i < term.size(); i++){
				auto _ = term[i];
				if (_[0] >= 'A' && _[0] <= 'Z'){
					termnum[i] = 1;
				}
			}
			for (int i = 0; i < term.size(); i++){
				auto _ = term[i];
				if (_ == "("){
					stk.push({"(", i});
				}
				else if (_ == ")"){
					w[i] = stk.top().second;
					stk.pop();
				}
			}
			
			for (int i = 0; i < term.size(); i++){
				auto _ = term[i];
				if (_[0] >= '0' && _[0] <= '9'){
					int mm = 0;
					for (int j = 0; j < _.size(); j++){
						mm = mm * 10 + (char)_[j] - '0';
					}
					if (mm == 0) mm = 1;
					if (term[i-1] == ")"){
						for (int j = w[i - 1] + 1; j < i; j++){
							if (term[j][0] >= 'A' && term[j][0] <= 'Z') termnum[j] *= mm;
						}
					}else{
						if (term[i-1][0] >= 'A' && term[i-1][0] <='Z') termnum[i-1] *= mm;
					}
				}
			}
			
			for (int i = 0; i < term.size(); i++){
				auto _ = term[i];
				if (_[0] >= 'A' && _[0] <= 'Z'){
					lcnt[_] += number * termnum[i];
				}
			}
		}
		
		for (int kk = 0; kk < rfml.size(); kk++){
			int number = rnum[kk];
			string sub = rfml[kk];
			vector <string> term;
			int i = 0;
			for (i = 0; i < sub.size();i++){
				if (sub[i] >= '0' && sub[i] <= '9'){continue;}
				else break;
			}
			for (; i < sub.size(); i++){
				
				string element ="";
				element += sub[i];
				if (sub[i] == '(') {term.push_back("(");}
				else if (sub[i] >= 'A' && sub[i] <= 'Z'){
					if (sub[i + 1] >= 'a' && sub[i + 1] <= 'z'){
						element += sub[i+1];
						i++;
					}
					term.push_back(element);
				}
				else if (sub[i] == ')'){term.push_back(")");}
				else if (sub[i] >= '0' && sub[i] <= '9'){
					string mm = "";
					for (;i < sub.size();i++){
						if (sub[i] >= '0' && sub[i] <= '9'){
							mm = mm + sub[i];
						}
						else {
							break;
						}
					}
					i--;
					term.push_back(mm);
				}
			}
			stack <pair<string, int>> stk;
			vector <int> w(term.size());
			vector <int> termnum(term.size());
			for (int i = 0; i < term.size(); i++){
				auto _ = term[i];
				if (_[0] >= 'A' && _[0] <= 'Z'){
					termnum[i] = 1;
				}
			}
			for (int i = 0; i < term.size(); i++){
				auto _ = term[i];
				if (_ == "("){
					stk.push({"(", i});
				}
				else if (_ == ")"){
					w[i] = stk.top().second;
					stk.pop();
				}
			}
			
			for (int i = 0; i < term.size(); i++){
				auto _ = term[i];
				if (_[0] >= '0' && _[0] <= '9'){
					int mm = 0;
					for (int j = 0; j < _.size(); j++){
						mm = mm * 10 + (char)_[j] - '0';
					}
					if (mm == 0) mm = 1;
					if (term[i-1] == ")"){
						for (int j = w[i - 1] + 1; j < i; j++){
							if (term[j][0] >= 'A' && term[j][0] <= 'Z') termnum[j] *= mm;
						}
					}else{
						if (term[i-1][0] >= 'A' && term[i-1][0] <='Z')termnum[i-1] *= mm;
					}
				}
			}
			
			for (int i = 0; i < term.size(); i++){
				auto _ = term[i];
				if (_[0] >= 'A' && _[0] <= 'Z'){
					rcnt[_] += number * termnum[i];
				}
			}
		}
	
		int flag = 1;
		for (auto _ : lcnt){
			string s = _.first;
			int x = rcnt[s];
			if (_.second != x){
				flag = 0;
				break;
			}
		}
		for (auto _ : rcnt){
			string s = _.first;
			int x = lcnt[s];
			if (_.second != x){
				flag = 0;
				break;
			}
		}
		if (flag == 1) puts("Y");
		else puts("N");
	}
	return 0;
}

/*
11
H2+O2=H2O
2H2+O2=2H2O
H2+Cl2=2NaCl
H2+Cl2=2HCl
CH4+2O2=CO2+2H2O
CaCl2+2AgNO3=Ca(NO3)2+2AgCl
3Ba(OH)2+2H2PO4=6H2O+Ba2(PO4)2
3Ba(OH)2+2H2PO4=Ba2(PO4)2+6H2O
4Zn+10HNO3=4Zn(NO3)2+NH4NO3+3H2O
4Na(Au(CN)2)+4NaOH=4Au+8NaCN+2H2O+O2
Cu+As=Cs+Au


*/
### CCF-CSP 2024 年 12 月考试信息概述 #### 考试背景与目标 CCF-CSP(中国计算机学会软件能力认证)是一项旨在评估个人编程能力和算法设计水平的测试。该考试通常每年举办多次,每次都会提供一系列具有挑战性的题目供考生解答。对于即将举行的 CCF-CSP 2024 年 12 月考试,虽然具体细节尚未完全公开,但可以根据以往的趋势推测其形式和内容。 根据过往经验[^1],CSP 认证考试一般由四道编程题组成,难度依次递增。前三题主要考察基本的数据结构、控制流以及简单的算法实现;第四题则可能涉及较复杂的算法设计或优化技巧。因此,建议考生重点练习前三个问题的基础部分,并逐步尝试解决第四个问题中的简化版本。 #### 解题策略与准备方法 针对即将到来的比赛,以下是几点备考建议: - **熟悉输入输出处理**:如同在相似度计算问题中所展示的一样,在程序开始阶段需正确获取所需数据量的信息,比如两个字符串列表各自的长度 `n` 和 `m` [^2]。 - **掌握核心知识点**: - 基础语法熟练运用; - 数据结构如数组、链表的操作; - 排序查找等经典算法的应用场景理解。 下面给出一段用于模拟读入多个整数值并存储到List集合内的Java代码片段作为示范: ```java import java.util.ArrayList; import java.util.Scanner; public class Main { public static void main(String[] args){ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); // 获取第一个序列大小 ArrayList<Integer> listA=new ArrayList<>(); for(int i=0;i<n;i++)listA.add(sc.nextInt()); int m=sc.nextInt();// 获取第二个序列大小 ArrayList<Integer> listB=new ArrayList<>(); for(int j=0;j<m;j++)listB.add(sc.nextInt()); System.out.println("Data Loaded Successfully!"); } } ``` 通过上述实例可以看出如何有效地管理大规模数据集以便后续分析比较操作得以顺利开展。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值