201912-3化學方程式

題目描述

CCF認證201912-3. 化學方程式題目描述

C++代碼

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<unordered_map>
using namespace std;
/*
利用unordered_map<string, int> ans存儲整個化學方程式中出現的原子及其對應個數。
先按=將整個方程式分成兩部分。左部分所有原子默認基本系數爲1,右部分所有原子默認基本系數爲-1。每部分最終的原子個數要乘上這個基本系數,這樣處理完整個方程式中所有原子,如果配平成功所有原子對應個數應該均爲0;否則有原子個數不爲0 。
對於按=將分成的兩部分,再按+分成多個化學式。針對每個化學式統計每種原子出現的個數。那麼如何處理帶()的化學式呢?我們可以採取遞歸處理的方法,針對遇到的每個(,找出其對應的)的位置,遞歸處理該()內的化學式,注意此時該()內的係數要乘上該()後緊鄰的數字。找出(對應的)的方法是,設立一個變量num,初始化爲1,遍歷(之後的所有字符,遇到一個(就讓num加1,遇到一個)讓num減1,那麼使num==0的)字符即爲(對應的)。
*/
int n;
string formula;
unordered_map<string, int>ans;
int computeDigit(int first, int last)
{
	int i = 0;
	for (; first <= last&&isdigit(formula[first]); first++)
	{
		i = i * 10 + formula[first] - '0';
	}
	return i == 0 ? 1 : i;
}
void f(int first, int last, int e)//計算formula的[f,l]區間的原子及對應係數 這是一個+分割的
{
	if (first == last || last - first == 1 && islower(formula[last]))
	{
		ans[formula.substr(first, last - first + 1)] += e;
		return;
	}
	//2nacl 先讓e * 最前面的數
	e *= computeDigit(first, last);
	for (int i = first, j = i + 1; i <= last; i = j, ++j)//遍歷化學式
	{
		if (isupper(formula[i]))//一般原子是2個字符或1個 NaOH
		{
			if (j <= last&&islower(formula[j]))//後面是小寫
				++j;
			int k = j;
			f(i, k - 1, e*computeDigit(j, last));//第三個參數思考一下
		}
		else if (formula[i] == '(')
		{
			for (int num = 1; num != 0; ++j)
			{
				if (formula[j] == '(')
					++num;
				else if (formula[j] == ')')
					--num;
			}
			int k = j;
			f(i + 1, k - 1, e*computeDigit(j, last));
		}
	}
}
void expression(int first, int last, int e)//按+分離出所有化學式
{
	for (int i = first,j=first; i <= last; i=j+1)
	{
		j = formula.find('+', i);
		if (j == string::npos || j > last)
			j = last + 1;
		f(i, j - 1, e);//可能沒有加號 然後直接找到最後
	}
}
int main()
{
	scanf("%d", &n);
	getchar();
	while (n--)
	{
		getline(cin, formula);
		ans.clear();//必須clear
		int k = formula.find('=');
		expression(0, k - 1, 1);
		expression(k + 1, formula.size() - 1, -1);
		int flag = 1;
		for (unordered_map<string, int> ::iterator it = ans.begin(); it != ans.end(); it++)
		{
			if (it->second != 0)
			{
				flag = 0;
				break;
			}
		}
		if (flag)
			printf("Y\n");
		else
			printf("N\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+2H3PO4=6H2O+Ba3(PO4)2
3Ba(OH)2+2H3PO4=Ba3(PO4)2+6H2O
4Zn+10HNO3=4Zn(NO3)2+NH4NO3+3H2O
4Au+8NaCN+2H2O+O2=4Na(Au(CN)2)+4NaOH
Cu+As=Cs+Au
*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章