7-5 Easy chemistry

In this question, you need to write a simple program to determine if the given chemical equation is balanced. Balanced means that the amount of elements on both sides of the “=” sign is the same.
H​2​​O+CO​2​​=H​2​​CO​3​​H​2​​O+CO​2​​=H​2​​CO​3​​H​2​​O+CO​2​​=H​2​​CO​3​​

We guarantees that each chemical equation satisfies the basic rules.

If you don’t know the basic rules of chemical equation writing, you can refer to the following conditions:

  • The chemical equation contains exactly one “=” sign.
  • For every chemical element, the first letter of each element is uppercase, and the rest of the letters are lowercase.
  • The number at the end of the element represents the amount of this element needed, If there is no number, it means only one element is needed.
  • Every chemical object may contain several chemical elements like NaCl.
    The number at the beginning of every chemical object represents the number of this object, If there is no number, it means only one object is needed.
  • Every chemical object will be connected by “+” sign.
  • Chemical reaction is considered to rearrange the atoms after they are broken up

Input

The first line contains a single integer T(1≤T≤100), indicating the number of test cases.

In the next T lines, each line contains a string S(1≤∣S∣≤100), representing a Chemical equation.

It is guaranteed that S only contains uppercase letters, lowercase letters, “=” sign and “+” sign, the sum of the amount of all elements will not exceed 2147483647.
Output

If the given chemical equation is balanced, please output “Easy!”, otherwise output “Hard!” (Without quotes).
Sample Input

3
H2O+CO2=H2CO3
2NaHCO3=Na2CO3+H2O+CO2
3Cu+8HNO3=3CuNO3+2NO+4H2O

Sample Output

Easy!
Easy!
Hard!

作者
tt
单位
浙江大学城市学院
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB

题意 : 给定一个化学方程式字符串,判断左右两边原子个数是否相等

  • 字符串有且仅有一个等于号"=""=""="
  • 等号两边是"物质A+物质B+...物质N""物质A+物质B+...物质N""物质A+物质B+...物质N"
  • 物质i物质_i物质i​由大小写字母和数字组成,形如2NaCO32NaCO32NaCO3
  • 对于2NaCO32NaCO32NaCO3,发现个数为:Na=2∗1,C=2∗1,O=2∗3Na=2*1,C=2*1,O=2*3Na=2∗1,C=2∗1,O=2∗3
  • 多组样例

这题看似别扭,但其实很简单,
2NaCO32NaCO32NaCO3可以看成是[numL][Name1][numR1][Name2][numR2]....[NameN][numRN][numL][Name_1][numR_1][Name_2][numR_2]....[Name_N][numR_N][numL][Name1​][numR1​][Name2​][numR2​]....[NameN​][numRN​]
用两个map统计等号左右两边的原子个数,最后比较两个map是否全等
把状态机画出来,再对着状态机写代码即可1A1A1A (调代码调了一上午)

状态图如下:
代码如下(一大堆又臭又长的if−elseif-elseif−else):

#define debug
#ifdef debug
#include <time.h>
#include "/home/majiao/mb.h"
#endif#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <math.h>#define MAXN ((int)1e5+7)
#define ll long long int
#define INF (0x7f7f7f7f)
#define fori(lef, rig) for(int i=lef; i<=rig; i++)
#define forj(lef, rig) for(int j=lef; j<=rig; j++)
#define fork(lef, rig) for(int k=lef; k<=rig; k++)
#define QAQ (0)using namespace std;#ifdef debug
#define show(x...) \
do { \cout << "\033[31;1m " << #x << " -> "; \err(x); \
} while (0)void err() { cout << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }
#endif#ifndef debug
namespace FIO {template <typename T>void read(T& x) {int f = 1; x = 0;char ch = getchar();while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }x *= f;}
};
using namespace FIO;
#endifint n, m, Q, K;
char buf[MAXN];
map<string, int> mp1, mp2; //map1代表等号左边的原子个数表//map2代表等号右边#define ch (buf[i])
#define Big(x) (x>='A' && x<='Z')
#define Small(x) (x>='a' && x<='z')
#define NUML (numL ? numL : 1)
#define NUMR (numR ? numR : 1)
#define Num(x) (x>='0' && x<='9')#define mp (*ptr)//to0是跳回状态0
#define to0 {name.clear();\status = numL = numR = 0;}void slove() {map<string, int>* ptr = &mp1; //初始状态为左边的mapint status = 0, numL = 0, numR = 0;string name = "", ptag = "map1 : ";//状态 : 0-初始状态, 1-读物质名字name,//      2-读原子个数numR,  3-读物质个数numLfor(int i=0; buf[i]; ) { //注意这里不要i++if(status == 0) { //起始状态if(Big(ch)) { //遇到大写 转化为1状态,读namestatus = 1;} else if(Num(ch)) { //遇到数字 转化为3状态, 读物质个数numLstatus = 3;}} else if(status == 1) { //1状态是读取名字if(Big(ch)) {if(!name.empty()) { //更新上一个名字到mapmp[name] += (NUML * NUMR);name.clear();}name.push_back(ch); //加入i ++;} else if(Num(ch)) { //遇到数字,说明要去读numR,原子个数status = 2;} else if(Small(ch)) { //小写也是上一个name的一部分name.push_back(ch);i ++;} else if(ch == '=') { //等号要切换map并回到初始状态mp[name] += (NUML * NUMR); //当然要先更新上一个nameptr = &mp2; //切换到右边的mapto0;i ++;} else if(ch == '+') { //遇到+要读下一个"2NaCO3"mp[name] += (NUML * NUMR);to0;i ++;}} else if(status == 2) { //状态2要读原子个数numRif(Big(ch)) { //遇到大写,说明当前原子的个数numR读完了,跳回1继续读namemp[name] += (NUML * NUMR); //更新0name.clear();numR = 0;status = 1;} else if(Num(ch)) { numR = numR * 10 + (ch - '0');i ++;} else if(Small(ch)) {} else if(ch == '=') { //等号同1里的等号mp[name] += (NUML * NUMR);ptr = &mp2;to0;i ++;} else if(ch == '+') { //加号同1里的加号mp[name] += (NUML * NUMR);to0;i ++;}} else if(status == 3) { //状态3是读总物质个数numLif(Big(ch)) { //遇到大写说明当前numL读完了,跳去读namemp[name] += (NUML * NUMR);numR = 0;name.clear();status = 1; //改成status = 0也可} else if(Num(ch)) {numL = numL * 10 + (ch - '0');i ++;} else if(Small(ch)) {} else if(ch == '=') {} else if(ch == '+') {}}}
#if 0mp1.erase(""), mp2.erase("");for(auto it : mp1)cout << "[" << it.first << "," << it.second << "], ";cout << endl;for(auto it : mp2)cout << "[" << it.first << "," << it.second << "], ";cout << endl;
#elsemp1.erase(""), mp2.erase(""); //删掉两个map的空串if(mp1.size() != mp2.size()) //两边原子种类数量不同,就noprintf("Hard!\n");else { //比较每个原子个数是否相同bool ok = true;for(auto it=mp1.begin(), it2=mp2.begin(); it!=mp1.end(); it++, it2++) {if(it->first!=it2->first || it->second!=it2->second)ok = false;}printf("%s\n", !ok ? "Hard!" : "Easy!");}
#endif
}int main() {#ifdef debugfreopen("test", "r", stdin);clock_t stime = clock();
#endifscanf("%d ", &Q);while(Q--) {mp1.clear(), mp2.clear();scanf("%s ", buf);n = strlen(buf);buf[n] = '+'; //字符串屁股后加入一个+,就不用单独处理字符串末尾了buf[n+1] = 0;slove();}#ifdef debugclock_t etime = clock();printf("rum time: %lf 秒\n",(double) (etime-stime)/CLOCKS_PER_SEC);
#endif return 0;
}

PTA Easy chemistry 化学方程式等价判定 string 状态机相关推荐

  1. 一篇让你读懂java中的字符串(String)

    目录 创建字符串 方式1 方式2 方式3 三种方式的内存图 方式1 方式2 方式3 总结 理解池的概念 回忆引用 字符串判断相等 判断字符串引用是否相等 代码1 代码2 代码3 代码4 总结 判断字符 ...

  2. python 状态机_可爱的 Python:使用状态机

    可爱的 Python:使用状态机 Python 中的算法和编程方法 David Mertz 博士 2000 年 8 月 01 日发布 什么是 Python? 请简要回顾本专栏中的 第一篇文章 ,Pyt ...

  3. c++ string replace_JAVA应用程序开发之String类常用API

    [本文详细介绍了JAVA应用开发中的String类常用API,欢迎读者朋友们阅读.转发和收藏!] 1 基本概念 API ( Application Interface 应用程序接口)是类中提供的接口, ...

  4. Java深入了解String对象

    一,从根本上认识java.lang.String类和String池 首先,我建议先看看String类的源码实现,这是从本质上认识String类的根本出发点.从中可以看到: 1,String类是fina ...

  5. golang string int int32 int64 float32 float64 time 互相转换

    目录 1.float64转int int转int64 2.string和int.int32.int64 3.string和float32.float64 4.string和time 5.转换函数说明 ...

  6. java中字符串的创建_【转载】 Java中String类型的两种创建方式

    本文转载自 https://www.cnblogs.com/fguozhu/articles/2661055.html Java中String是一个特殊的包装类数据有两种创建形式: String s ...

  7. Java学习笔记(六)--字符串String类

    文章目录 字符串 一.String 类 1.1 声明字符串 1.2 创建字符串 二.连接字符串 2.1 连接多个字符串 2.2 连接其他数据类型 三.获取字符串信息 3.1 获取字符串长度 3.2 字 ...

  8. 深入理解Java中的String

    一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class Stringimplements java.io.Seri ...

  9. C++中对String的各种操作

    1.string的各种动态.静态赋值 //静态 string s1=("abckd"); string s2("bbbbb"); string s3(s1); ...

最新文章

  1. Google Adsense实用防踢技巧总结
  2. 计算机视觉的发展历史
  3. ASP之防止外部数据提交的脚本
  4. 【2012百度之星/资格赛】H:用户请求中的品牌
  5. 66319d电源使用说明书_矿用防爆交换机如何正确安装调试和使用?
  6. BugkuCTF-MISC题宽带信息泄露
  7. php如何删除服务器图片,php如何删除服务器文件
  8. OpenMP并行加速笛卡尔乘积
  9. linux系统中清空文件内容的三种方法
  10. 如何用iso文件制作U盘启动
  11. java微信聊天机器人源码_三步轻松打造微信聊天机器人(附源码)
  12. python f检验 模型拟合度_模型评估指标(RMSE、MSE、MAE、R2准确率、召回率、F1、ROC曲线、AUC曲线、PR曲线)...
  13. python词云生成
  14. EPICS简单的设备支持程序
  15. 【CSP-J】【图论】【最短路】加工零件
  16. [翻译]2020年综述:基于深度学习的视频超分辨率
  17. 大恒相机开发问题(错误码: -8)无法打开相机
  18. OrangePi3开发板使用指南
  19. vs为什么打了断点不断_2019年亚洲羽毛球锦标赛半决赛焦点对阵:陈雨菲vs山口茜 德查波/莎西丽vs王懿律/黄东萍 周天成vs石宇奇...
  20. 便宜运行linux芯片,个头小本事大:13 种 20 美元以下的树莓派 Zero 替代品 | Linux 中国...

热门文章

  1. 基于WebSocket实现一个简易的群聊功能
  2. JS字符串padStart()方法,padEnd()方法
  3. OFDMA,LFDMA以及IFDMA的PAPR对比仿真
  4. 大点干!早点散----------深入剖析GFS分布式文件系统
  5. python中scapy模块的使用
  6. 【obs】发送前丢帧算法及帧优先级设置
  7. 机器学习之先验分布,后验分布,共轭先验分布
  8. 最全的Python网站开发库!整理出来了!
  9. HTML5常见面试题及答案(一)
  10. C语言七巧板游戏制作,绘本里的七巧板游戏