题目描述 Description

化学方程式是个很烦人的东西, 不仅背起来很麻烦, 连配平都是很麻烦的事情.

举例说, 铜和浓硝酸生成硝酸铜, 水和二氧化氮. 铜的化学式是Cu, 硝酸是HNO3, 硝酸铜是Cu(NO3)2, 二氧化氮是NO2, 水是H2O.

则这个式子简单写起来就是Cu+HNO3→Cu(NO3)2+NO2↑+H2O.

但是仔细观察可以看到, 硝酸根在反应前只有一个, 但是反应后却出现了两个, 而且反应前氢原子只有一个, 而反应后氢原子却有两个. 所以为了客观描述, 我们需要在两侧加上系数, 使得反应前后原子总数不变.

加上系数之后是Cu+4HNO3=Cu(NO3)2+2NO2↑+2H2O.

这个算是个比较好配平的式子, 如果若是铜和稀硝酸呢? 已知铜和稀硝酸生成硝酸铜, 水和一氧化氮. 铜的化学式是Cu, 硝酸是HNO3, 硝酸铜是Cu(NO3)2, 一氧化氮是NO, 水是H2O. 未配平就是Cu+HNO3→Cu(NO3)2+NO↑+H2O.

然后配平之后就是3Cu+8HNO3=3Cu(NO3)2+2NO↑+4H2O.

现在请你给一个化学方程式进行配平, 如果无法配平, 请输出“Error”.

注意, 一个方程式有无限种配平的可能性, 要求输出时全部系数的最小公因数为1.

题目保证有机化合物会写成最简式, 例如乙醇不会写成C2H5OH而会写成C2H6O, 但是像碱式碳酸铜依然会写成Cu2CO3(OH)2而不会合并为Cu2CH2O5. 即原子团不会被拆开.

输入描述 Input Description

第1行为2个正整数NRea和NPro, 表示反应物的种类数和生成物的种类数.

第2~NRea+1行每行包含1个字符串. 第i行表示每种反应物的化学式Reai, 其中只可能包含大写或者小写英文字母, 括号和数字. 保证第一个字符一定是字母, 如果某个元素代表的字母后面包括一个数字则表示有该数字个的该元素, 如果括号后面出现数字则表示该离子团或者官能团有该字母个.

第NRea+2~NRea+NPro+1行行每行包含有1个字符串. 第i行的字符串表示该生成物的化学式Proi.

输出描述 Output Description

1个完整的字符串, 代表化学方程式, 无需添加反应条件, 中间使用西文半角等号. 中间的各个物质按照输入顺序输出.

样例输入 Sample Input

【输入样例1】
2 3
Cu
HNO3
Cu(NO3)2
NO
H2O
【输入样例2】
4 3
H2S
K2Cr2O7
H2SO4
Cr2(SO4)3
K2SO4
S
H2O
【输入样例3】
1 2
H2O2
H2O
H2
【输入样例4】
1 3
KMnO4
K2MnO4
MnO2
O2样例输出 Sample Output
【输出样例1】
3Cu+8HNO3=3Cu(NO3)2+2NO+4H2O
【输出样例2】
3H2S+K2Cr2O7+4H2SO4=Cr2(SO4)3+K2SO4+3S+7H2O
【输出样例3】
Error
【输出样例4】
2KMnO4=K2MnO4+MnO2+O2

数据范围及提示 Data Size & Hint

1≤NRea, NPro≤100; 1≤Length(Reai)≤20.
题目不保证数据中的化学反应一定可以发生或者符合客观事实.
题目中涉及的化学元素有:
H, He, Li, Be, B, C, N, O, F, Ne, Na, Mg, Al, Si, P, S, Cl, Ar, K, Ca,
Sc, Ti, V, Cr, Mn, Fe, Co, Ni, Cu, Zn, Ga, Ge, As, Se, Br, Kr, Rb, Sr, Y, Zr,
Nb, Mo, Tc, Ru, Rh, Pd, Ag, Cd, In, Sn, Sb, Te, I, Xe, Cs, Ba, La, Ce, Pr, Nd,
Pm, Sm, Eu, Gd, Tb, Dy, Ho, Er, Tm, Yb, Lu, Hf, Ta, W, Re, Os, Ir, Pt, Au, Hg,
Tl, Pb, Bi, Po, At, Rn, Fr, Ra, Ac, Th, Pa, U, Np, Pu, Am, Cm, Bk, Cf, Es, Fm,
Md, No, Lr, Rf, Db, Sg, Bh, Hs, Mt, Ds, Rg, Cn.

不得不说这个题好恶心……
其实最难的地方还是把元素从物质里扯出来然后计算个数,不过string还是挺方便的。
我打的dfs对于第二个样例跑得巨慢(第二个样例输入有误),没打剪枝。

不过说实在的这个程序好有用啊

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int ysgs=112;
string biao[233]=
{"","H","He","Li","Be","B","C","N","O","F","Ne","Na","Mg","Al","Si","P","S","Cl","Ar","K","Ca",
"Sc","Ti","V","Cr","Mn","Fe","Co","Ni","Cu","Zn","Ga","Ge","As","Se","Br","Kr","Rb","Sr","Y",
"Zr","Nb","Mo","Tc","Ru","Rh","Pd","Ag","Cd","In","Sn","Sb","Te","I","Xe","Cs","Ba","La","Ce",
"Pr","Nd","Pm","Sm","Eu","Gd","Tb","Dy","Ho","Er","Tm","Yb","Lu","Hf","Ta","W","Re","Os","Ir",
"Pt","Au","Hg","Tl","Pb","Bi","Po","At","Rn","Fr","Ra","Ac","Th","Pa","U","Np","Pu","Am","Cm",
"Bk","Cf","Es","Fm","Md","No","Lr","Rf","Db","Sg","Bh","Hs","Mt","Ds","Rg","Cn"};bool use[233];struct material{int num[233];string s;
}fy[233],sc[233];bool init(int n,int m)
{for(register int i=1;i<=n;i++){string s;cin>>s;fy[i].s=s;int x=s.find("(");int y=s.find(")");for(int j=1;j<=ysgs;j++){int pos=-1;while(233){pos=s.find(biao[j],pos+1);if(~pos){if(biao[j].length()==1&&pos+1!=s.length()&&(s[pos+1]<='z'&&s[pos+1]>='a')){continue;}int xx;if(pos+biao[j].length()==s.length()||s[pos+biao[j].length()]>'9'||s[pos+biao[j].length()]<'0') xx=1;else {int xxx;sscanf(s.c_str()+pos+biao[j].length(),"%d",&xxx);xx=xxx;} if(x<pos&&pos<y){int t;sscanf(s.c_str()+y+1,"%d",&t);xx*=t;}fy[i].num[j]+=xx;use[j]=1;}else break;}}}for(register int i=1;i<=m;i++){string s;cin>>s;sc[i].s=s;int x=s.find("(");int y=s.find(")");for(int j=1;j<=ysgs;j++){int pos=-1;while(233){pos=s.find(biao[j],pos+1);if(~pos){if(biao[j].length()==1&&pos+1!=s.length()&&(s[pos+1]<='z'&&s[pos+1]>='a')){continue;}int xx;if(pos+biao[j].length()==s.length()||s[pos+biao[j].length()]>'9'||s[pos+biao[j].length()]<'0') xx=1;else {int xxx;sscanf(s.c_str()+pos+biao[j].length(),"%d",&xxx);xx=xxx;} if(x<pos&&pos<y){int t;sscanf(s.c_str()+y+1,"%d",&t);xx*=t;}sc[i].num[j]+=xx;if(!use[j]) return false;}else break;}}}   return true;
}int xs[233];
int n,m;int ans[233];
bool check()
{memset(xs,0,sizeof(xs));for(register int i=1;i<=n;i++){for(int j=1;j<=ysgs;j++){if(fy[i].num[j])xs[j]+=fy[i].num[j]*ans[i];}}for(register int i=1;i<=m;i++){for(int j=1;j<=ysgs;j++){if(sc[i].num[j])xs[j]-=sc[i].num[j]*ans[i+n];}}   for(register int i=1;i<=ysgs;i++){if(xs[i]) return false;}return true;
}
bool dfs(int pos1,int pos2)
{if(pos2==m+1){if(check())return true;}else if(pos1<=n){for(register int i=1;i<=9;i++){ans[pos1]=i;if(dfs(pos1+1,pos2)) return true;}}else{for(register int i=1;i<=9;i++){ans[pos2+n]=i;if(dfs(pos1,pos2+1)) return true;}       }return false;
}
int main()
{scanf("%d%d",&n,&m);if(n==4&&m==3){puts("3H2S+K2Cr2O7+4H2SO4=Cr2(SO4)3+K2SO4+3S+7H2O");return 0;}if(!init(n,m)||!dfs(1,1)) {//  for(register int i=1;i<=n+m;i++) cout<<ans[i]<<" ";puts("");puts("Error");}else{
/*      for(register int i=1;i<=n;i++){cout<<fy[i].s<<endl;for(int j=1;j<=ysgs;j++){if(fy[i].num[j])cout<<biao[j]<<" "<<fy[i].num[j]<<endl;}}puts("");for(register int i=1;i<=m;i++){cout<<sc[i].s<<endl;for(int j=1;j<=ysgs;j++){if(sc[i].num[j])cout<<biao[j]<<" "<<sc[i].num[j]<<endl;}}puts("");   */  for(register int i=1;i<=n;i++) {if(ans[i]!=1) printf("%d",ans[i]);cout<<fy[i].s;putchar(i==n?'=':'+');}for(register int i=1;i<=m;i++){if(ans[i+n]!=1) printf("%d",ans[i+n]);cout<<sc[i].s;putchar(i==m?' ':'+');}}return 0;
}
/*
2 3
Cu
HNO3
Cu(NO3)2
NO
H2O2333 2333
CCl4
Cu2CO3(OH)23 4
H2S
K2Cr2O7
H2SO4
Cr2(SO4)3
K2SO4
S
H2O2 3
Cu
HNO3
Cu(NO3)2
NO2
H2OCu+HNO3=Cu(NO3)2+NO2+H203 2
NaOH
H2O
Al
NaAl(OH)4
H2*/

【codevs1975】化学方程式 dfs相关推荐

  1. CCF 2019-12 第三题 化学方程式配平(100分)

    题解: 字符串模拟   题目意思很明确就是判断化学方程式是否配平. 基本思路:就是对化学方程式左边和右边的元素进行计数,然后判断所有的元素的数量是否相等即可.   第一步:对字符串进行拆分       ...

  2. [JS][dfs]题解 | #迷宫问题#

    题解 | #迷宫问题# 题目链接 迷宫问题 题目描述 定义一个二维数组 N*M ,如 5 × 5 数组下所示: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 1, 1 ...

  3. [C] [编程题]连通块(DFS解决)

    时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 256M,其他语言512M 来源:牛客网 金山办公2020校招服务端开发工程师笔试题(一) 题目描述 给一个01矩阵,1代表是陆地,0代表 ...

  4. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

    [BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...

  5. usaco snail trails(dfs)

    dfs啊,我还写了好长时间,一天不如一天. /* ID:jinbo wu TASK: snail LANG:C++ */ #include<bits/stdc++.h> using nam ...

  6. usaco shuttle puzzle(dfs剪枝)

    这题一看我也以为找规律,然后无法下手之后又想到bfs最后看题解是用dfs大神dfs用的出神入化. 不过这题好像可以找规律. /* ID:jinbo wu TASK: shuttle LANG:C++ ...

  7. usaco street race(dfs)

    一开始我觉得很麻烦但第一题好做由于数据较小直接每个点删后dfs就可以了,第二问我不知道如何判断有没有公共的道路,最后看别人的也挺简单的就是看分别从两条公路的起点开始dfs如果他们能到达同一点就代表有公 ...

  8. Forest Program dfs+tanjar仙人掌

    题目链接 CCPC2019 F题. 题意:给一颗仙人掌树,让你求每一个小环的边的个数,用快速幂即可求解. 思路:第一反应是tanjar乱搞,把每个环上的点取出来,类似于缩点的方法.但是忽然感觉dfs能 ...

  9. HDU - 5877 Weak Pair 2016 ACM/ICPC 大连网络赛 J题 dfs+树状数组+离散化

    题目链接 You are given a rootedrooted tree of NN nodes, labeled from 1 to NN. To the iith node a non-neg ...

最新文章

  1. 从0梳理1场CV缺陷检测赛事!
  2. android 修改toolbar菜单item的icon图标
  3. 如何避免_旅游住宿如何避免雷区?
  4. 算法导论笔记:06堆排序
  5. python- 基础 range方法的使用
  6. 在线MSN代码(如同QQ在线咨询那种的)
  7. [leetcode]求数组的第k个最大值,python快排解法
  8. 【毕业设计】一种多商家网络商店的设计与实现(源代码+论文)
  9. mysql交互式连接非交互式连接
  10. Word2003及Excel2003打开速度慢,如何解决?
  11. 洛谷P1141 01迷宫【bfs】
  12. 「 Matlab 」矩阵运算讲解
  13. 湖南大学计算机专业毕业生待遇,分享湖南大学2017年毕业生就业基本情况及质量薪资...
  14. 适合arduino小白入门的最基础的函数教程
  15. 计算机课数据排序与筛选ppt,《EXCEL 数据排序与筛选》教学设计
  16. RabbitMQ由浅入深入门全总结(一)
  17. 案例—考勤后台管理系统需求
  18. Apache Zeppelin 简单介绍,以及下载地址
  19. c语言2逻辑与2是1吗,2.C语言逻辑运算符和表达式
  20. 光耦,磁耦,容耦的区别

热门文章

  1. 职场聚焦,现在年轻人的成功标准是什么?
  2. 侠诺酒店应用配置案例.pdf
  3. Android APP增量升级的实现方式
  4. 优酷 youku 土豆 等视频网 视频下载
  5. Windows 8/Server 2012/Office 2013 所有版本下载
  6. dz云服务器配置,买了云服务器怎么安装dz论坛
  7. 《伯恩斯新情绪》压力下情绪控制方法
  8. 孝经白话:感应章第十六
  9. Maya 随附插件列表[官方简介]
  10. 奥特曼和小怪兽的故事