Articles12
Tags2
Categories0

CSP-化学方程式(模拟)


传送门(需要登录)

题意:化学方程式,也称为化学反应方程式,是用化学式表示化学反应的式子。给出一组化学方程式,请你编写程序判断每个方程式是否配平(也就是方程式中等号左右两边的元素种类和对应的原子个数是否相同)。
本题给出的化学方程式由大小写字母、数字和符号(包括等号=、加号+、左圆括号和右圆括号)组成,不会出现其他字符(包括空白字符,如空格、制表符等),化学方程式的格式与化学课本中的形式基本相同(化学式中表示元素原子个数的下标用正常文本,如H2O写成H2O),用自然语言描述如下:

化学方程式由左右两个表达式组成,中间用一个等号三连接,如2H2+O2=2H2O;
表达式由若干部分组成,每部分由系数和化学式构成,部分之间用加号+连接,如2H2+O2、2H2O;
系数是整数或空串,如为空串表示系数为1;
整数由一个或多个数字构成;
化学式由若干部分组成,每部分由项和系数构成,部分之间直接连接,如H2O、CO2、Ca(OH)2、Ba3(PO4)2;
项是元素或用左右圆括号括起来的化学式,如H、Ca、(OH)、(P04);
元素可以是一个大写字母,也可以是一个大写字母跟着一个小写字母,如H、O、Ca。

输入: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
输出:N
Y
N
Y
Y
Y
Y
Y
Y
Y
N

思路:一道小模拟吧算是,难点主要在嵌套的括号这里,我用了递归实现,传回去的参数我选择了

map<string,int>。其他也没什么好说的。

题外话:这应该是近期的最后一篇博文了,这个博客近期应该是闲置了。顺便这道题我也是1A,小小纪念一下。

话不多说,直接上代码。作为一个小模拟50行出头还是很可以的(

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+50;
char ch[maxn],tmp[maxn],dig[maxn];
map<string,int>mp; int j,p;
bool isdig(char x){
    return x>='0'&&x<='9';
}bool islower(char x){
    return x>='a'&&x<='z';
}int getdig(){ int tp=0,xs=0;
    while(isdig(tmp[j])&&j<p){
        dig[tp++]=tmp[j];j++;
    }dig[tp]=0;xs=atoi(dig);if(!xs) xs=1;
    return xs;
}map<string,int> analyze(){
    map<string,int> mm,now;
    while(j<p){ string x;
        if(tmp[j]=='('){ 
            j++;mm=analyze();
            for(auto y:mm) now[y.first]+=y.second;
        }else if(tmp[j]==')'){
            j++;int xs=getdig();
            for(auto y:now){
                //cout<<y.first<<y.second*xs<<endl;
                now[y.first]=y.second*xs;
            }return now;
        }else{
            x+=tmp[j++];if(islower(tmp[j])) x+=tmp[j++];
            int xs=getdig();now[x]+=xs;
        }
    }return now;
}void solve(){
    scanf("%s",ch);mp.clear(); 
    int n=strlen(ch);p=0; int flg=1;
    for(int i=0;i<=n;i++){
        if(i==n||ch[i]=='+'||ch[i]=='='){ j=0;
            tmp[p]=0;int xs=getdig();
            map<string,int> mm=analyze();p=0;
            for(auto y:mm){
                //cout<<y.first<<y.second*xs<<endl;
                mp[y.first]+=y.second*xs*flg; 
            }if(ch[i]=='=') flg=-1;
        }else tmp[p++]=ch[i];
    }for(auto y:mp) if(y.second!=0) return (void)printf("N\n");
    printf("Y\n");
}
int main(){
    int t;scanf("%d",&t);while(t--) solve();
    return 0;
}

我们有缘再会~

​ By FrogGLeader

Author:西瓜喵喵.
Link:https//:ForgGYLH.github.io/2020/06/10/CSP/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可