CCF 2019-12 化学方程式

CCF 2019-12 化学方程式

链接 :http://118.190.20.162/view.page?gpid=T98

题意:化学方程式的配平
题解:万年无敌大模拟
  1. 使用数组进行 hash 储存化学方程式的元素

  2. 对括号进行递推处理

  3. 注意前面的参数和后面参数

    样例不能复制真香

样例输入
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
代码
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = 1e3+5;
char s[MAXN];
int a[MAXN];
bool ex(string x,int flag){
    int cnt=0,ret=0,res=0,i=0;
    for(i=0;i<x.length();++i){
        if((x[i]>='A'&&x[i]<='Z')||(x[i]>='a'&&x[i]<='z')){
            if((x[i]>='A'&&x[i]<='Z'))cnt=cnt*29+(x[i]-'A'+1),ret++;
            else cnt=cnt*29+(x[i]-'a'+1);
            if(ret>=2)return false;
        }
        else break;
    }
    for(;i<x.length();++i)
        if(x[i]>='0'&&x[i]<='9')
            res=res*10+x[i]-'0';
        else return false;
    if(res)flag*=res;
    a[cnt]+=flag;
    return true;
}
int toint(string x){
    string y;
    int cnt=0,i,ret=0;
    for(i=1;i<x.length();++i){
        if(cnt==0&&x[i]==')'){
            ++i;
            break;
        }
        if(x[i]=='(')cnt++;
        if(x[i]==')')cnt--;
        y+=x[i];
    }
    for(;i<x.length();++i)
        ret=ret*10+x[i]-'0';
    if(ret);
    else ret=1;
    return ret;
}
string tostring(string x){
    string y;
    int cnt=0,i=1,ret=0;
    for(;i<x.length();++i){
        if(cnt==0&&x[i]==')'){
            ++i;
            break;
        }
        if(x[i]=='(')cnt++;
        if(x[i]==')')cnt--;
        y+=x[i];
    }
    return y;
}
void slove(string x,int flag){
    // cout<<x<<" "<<flag<<endl;
    if(ex(x,flag))
        return;
    int pos=0,res=0,cnt=0,i=0,j=x.length()-1;
    for(;;++i){
        if(x[i]>='0'&&x[i]<='9')pos=pos*10+x[i]-'0';
        else break;
    }
    if(pos)flag*=pos;
    string y;
    for(;i<x.length();++i){
        if(x[i]=='(')cnt++;
        if(x[i]==')')cnt--;
        if(cnt==0&&(i+1==x.length()||(x[i+1]>='A'&&x[i+1]<='Z')||x[i+1]=='(')){
            y+=x[i];
            int b=flag;
            if(y[0]=='('){
                b*=toint(y);
                y=tostring(y);               
            }
            slove(y,b);     
            y.clear();            
        }
        else y+=x[i];
    }
}
int main(){
    int T;
    string t;
    scanf("%d",&T);
    while(T--){
        memset(a,0,sizeof(a));
        int flag=1;
        scanf("%s",s);
        t.clear();
        int ls=strlen(s);
        for(int i=0;i<=ls;++i){
            if(i==ls||s[i]=='+'||s[i]=='='){
                slove(t,flag);
                t.clear();
                if(s[i]=='=')flag=-1;
            }
            else t+=s[i];
        }
        int f=1;
        for(int i=0;i<=1000;++i){
            if(a[i]){
                f=0;break;
            }
        }
        if(f)cout<<"Y"<<endl;
        else cout<<"N"<<endl;
    }
    return 0;
}
新赛季的开始
原文地址:https://www.cnblogs.com/VagrantAC/p/12666126.html