题解:

字符串模拟
  题目意思很明确就是判断化学方程式是否配平。
基本思路:就是对化学方程式左边和右边的元素进行计数,然后判断所有的元素的数量是否相等即可。
  第一步:对字符串进行拆分
     1、以 ‘=’ 进行拆分,将字符串分为左右两个串
     2、分别将左右两个串以 ‘+’ 进行拆分,得到一个个的化学式
  第二步:提取化学式最外面的倍数,比如3H2O,需要提取3,需要对内部元素都乘以3。
  第三步:dfs单独对一个化学式进行处理,为什么要用dfs?因为化学式会出现括号嵌套的情况,需要dfs对每个括号单独处理。注意需要记录倍数,下一次要将倍数计算好后传入,每一次计数都需要对倍数进行处理。
细节:
  1、元素为一个大写或者一个大写一个小写
  2、多层括号嵌套
  3、括号后面的数字,需要转换为倍数传入
  4、时刻注意防止越界
  5、对空串单独判断

复杂度分析:对一个字符串扫一遍为O(len) ,由于含有括号,需要对字符串进行切割,字符串切割复杂度为O(len),所以每一个字符串处理复杂度为O(len2),map复杂度为O(mlog2(m))小于O(len2),复杂度取大的。n个字符串,总复杂度为O(n(len2))

代码(有注释):

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false)
#define ll long long
#define maxn 1005
#define inf 1000000000//对字符串分割,分隔符为sp
vector<string> split_str(string str,char sp)
{vector<string>V;for(int i=0; i<str.size();){string ss="";while(i<str.size()&&str[i]!=sp){ss.push_back(str[i]);i++;}i++;if(ss!="")V.push_back(ss);}return V;
}//将string形式的数字转换为Int
int get_num(string num)
{int num1=0;int ten=1;for(int k=num.size()-1; k>=0; k--){num1+=(num[k]-=48)*ten;ten*=10;}return num1;
}/**对单个化学式进行计数:利用dfs对括号进行拆解,同时记录每次记录倍数对于非括号内的,直接计数即可(当然要乘以倍数)比如 4AL(Au(CN)2)3  下一次dfs将传入 Au(CN)2 传入倍数3
**/
void dfs(map<string,int>&m1,string str,int num1)
{for(int k=0; k<str.size();){if(str[k]=='('){k++;int num_c=1,num_f=0;int j;for(j=k; j<str.size(); j++){if(str[j]=='(')num_c++;if(str[j]==')'){num_f++;if(num_f==num_c)break;}}int len=j-k;string num="";j++;for(; j<str.size(); j++){if(str[j]>='0'&&str[j]<='9')num.push_back(str[j]);elsebreak;}int num2=1;if(num!="")num2=get_num(num);//cout<<"k="<<k<<",len="<<len<<",str="<<str.substr(k,len)<<",num1="<<num1*num2<<"\n";dfs(m1,str.substr(k,len),num1*num2);//cout<<num<<"\n";k+=len+num.size()+1;//cout<<"k="<<k<<"\n";}else{string xx="";xx.push_back(str[k]);if(k+1<str.size()&&str[k+1]>='a'&&str[k+1]<='z'){xx.push_back(str[k+1]);k++;}k++;string num="";while(k<str.size()&&str[k]>='0'&&str[k]<='9'){num.push_back(str[k]);k++;}int num2=1;if(num!="")num2=get_num(num);m1[xx]+=num2*num1;}}
}/**1、对化学方程式左边或者右边进行处理2、处理化学式初始倍数,如4AL(Au(CN)2)3 初始倍数为最前面的43、分别处理每个化学式 dfs
**/
void get_map(map<string,int>&m1,vector<string>&V1)
{for(int j=0; j<V1.size(); j++){string strid=V1[j];string num="";for(int k=0; k<V1[j].size(); k++){if(V1[j][k]>='0'&&V1[j][k]<='9')num+=V1[j][k];elsebreak;}int num1;if(num!=""){reverse(V1[j].begin(),V1[j].end());for(int k=0; k<num.size(); k++)V1[j].pop_back();reverse(V1[j].begin(),V1[j].end());//cout<<V1[j]<<" ";num1=get_num(num);}elsenum1=1;dfs(m1,V1[j],num1);}
}//判断两个map是否相等
bool equal_map(map<string,int>&m1,map<string,int>&m2)
{return m1==m2;
}//打印map
void print_map(map<string,int>&m1)
{for(map<string,int>::iterator p=m1.begin(); p!=m1.end(); p++){cout<<(*p).first<<","<<(*p).second<<"\n";}cout<<"---------------\n";
}int main()
{IOS;ll n;cin>>n;for(int i=1; i<=n; i++){map<string,int>m1,m2;string str;cin>>str;vector<string>V=split_str(str,'=');vector<string>V1=split_str(V[0],'+');vector<string>V2=split_str(V[1],'+');get_map(m1,V1);get_map(m2,V2);/*cout<<"m1:\n";print_map(m1);cout<<"m2:\n";print_map(m2);*/if(equal_map(m1,m2))cout<<"Y\n";elsecout<<"N\n";}return 0;
}

后记:此题模了两小时,CCF大模拟题果然名不虚传

CCF 2019-12 第三题 化学方程式配平(100分)相关推荐

  1. 【自己的小玩具程序】化学方程式配平【测试中】【未完成】

    化学元素周期表(Element.txt): 1    H    氢    1 2    He    氦    4 3    Li    锂    7 4    Be    铍    9 5    B  ...

  2. 用python实现化学方程式配平

    化学方程式配平是指调整化学反应的化学方程式,使得反应中所有的化学元素的原子数目在反应开始和反应结束时相等. 下面是一个简单的 Python 代码,用于配并化学方程式: ``` python 输入化学方 ...

  3. CCF CSP 2019-9-1 小明种苹果 C语言100分

    CCF CSP 2019-9-1 小明种苹果 C语言100分 小明种苹果 完成时间11-18 16:54 代码长度510B C 正确 100分 耗时93ms 空间使用6.167MB 这道题简单,仅附上 ...

  4. 有机物燃烧的化学方程式配平(洛谷P1994题题解,Java语言描述)

    题目要求 P1994题目链接 分析 我太菜了,亏得我高中时期还虐(or被虐)生化,如今多年过去竟然没分析出来坑点,我太菜了. 我开始盲目认为"元素守恒",所以对HHH原子数求和, ...

  5. ccf化学方程式配平检验

    样例输入: 11 H2+O2=H2O 2H2+O2=2H2O H2+Cl2=2NaCl H2+Cl2=2HCl CH4+2O2=CO2+2H2O CaCl2+2AgNO3=Ca(NO3)2+2AgCl ...

  6. CCF csp软件能力认证 第15次 第5题 管道清洁 java 100分

    题目csp模拟考试系统201812-5的题目. 我的java张老师是负责csp的,于是java的一个作业就是做这一套题.用java写,行,c++转java而已,写算法题嘛,基本语法懂了就好了,就边学边 ...

  7. Day9 化学方程式配平

    该题的难点在于括号的嵌套,如Na6((OH)(OH)2)3,比如OH在跳出嵌套之后需乘以紧接着其外的嵌套下标,我的解法是先一遍处理以下找到每个左括号和与之配置的右括号的位置,然后使用递归,每遇到左括号 ...

  8. 最佳答案 html5中不使用这些属性,[东北师范大学]《《HTML5开发基础与应用》2019年11月考试期末作业考核(100分)...

    试卷总分:100    得分:100 第1题,HTML5中具有boolean属性变更的元素不包括( ). A.true B.checked C.selected D.disabled 正确答案: 第2 ...

  9. csp第二题火车购票c++100分运行0ms(不会见缝插针的同学只能拿90分)

    这是个水题但是大部分人就只拿到90分 why? 我分析了一下大家应该是有一种情况没有考虑 所有车厢内没连续座位则应该安排在编号最小的几个空位,这个小细节应该是大部分人没注意到的 就是兄弟们没有见缝插针 ...

最新文章

  1. 请谈一下Spring MVC的工作原理是怎样的?
  2. android高德自定义图标,Android 高德地图显示在线图标
  3. WPF实现背景透明磨砂,并通过HandyControl组件实现弹出等待框
  4. STEAM教育风口正劲,如何培养STEAM思维?
  5. 一段简单的打印代码(c#)
  6. [转载]Validation of viewstate MAC failed异常的原因及解决方法
  7. 【英语学习】【Level 08】U02 Movie Time L6 Blockbuster
  8. python爬虫课程设计摘要_爬虫课程设计(爬虫代码)
  9. python写出雷霆战机_大一新生苦心研学Java半个月,独立写出雷霆战机到处自诩天才!牛...
  10. 学计算机买戴尔笔记本哪款,戴尔笔记本大学生用,买哪款比较好?
  11. Struts1框架轻易入门,经典示例
  12. ❤️肝下25万字的《决战Linux到精通》笔记,你的Linux水平将从入门到入魔❤️【建议收藏】
  13. 跳过selenium检测爬取淘宝直通车
  14. access open 知乎_必备技能!国际汇款SCI Open Access费用
  15. java newline_Java 输出文件通过 BufferedWriter.newline() 方法换行
  16. 【英语学习】【WOTD】hamartia 释义/词源/示例
  17. 简要分析用MD5加密算法加密信息(如有疑问,敬请留言)
  18. 线下门店管理运营 线下门店数据分析
  19. 【linux服务器】使用csdn云主机的体验与问题
  20. linux指令——刘雯丽

热门文章

  1. java深度学习框架Deeplearning4j实战(一)BP网络分类器
  2. 【通义听悟】音视频内容AI效率工具(包含公测福利)
  3. 移动硬盘格式化?想要恢复硬盘那就看这里!
  4. 给出以下程序,制作makefile文件,编译出可执行文件
  5. 记springboot项目POM文件第一行报错 Unknown Error
  6. 金蝶k3单据编码规则_金蝶K3 Wise 用SQL生成单号(单据编号)及单据内码(单据ID)
  7. 数据查询必备技能SQL调优:Mysql什么情况下不走索引
  8. 手把手教你学习IEC104协议和编程实现 八-协议的运行态(带时标的变位遥信及对时功能)
  9. 请教游戏高手一款外国游戏名称和下载地址
  10. 制作CSS绚烂效果的三种属性