csp 201912-3 化学方程式

csp 201912-3 化学方程式

起因

感觉csp的第三题还有点意思,所以再作一道.

经过

看到这题,立马明白,
这是要我变成

人肉yacc

至于这是LL,LR(0),LR(1)我也没搞清楚.

结果

调了一会,调出来了.

#include <bits/stdc++.h>

using namespace std;

typedef map<string,int> Elem;

inline bool upper(char c) { return 'A'<=c&&c<='Z';}
inline bool lower(char c) { return 'a'<=c&&c<='z';}
inline bool digit(char c) { return '0'<=c&&c<='9';}

char s[1001];
int i;

Elem parseFormular();
string parseElement() {//OK!
    string ret;
    ret+=s[i++];
    if(lower(s[i]))ret+=s[i++];
    return ret;
}

int parseCoef() {//OK!
    int ret=0;
    while(digit(s[i]))ret*=10,ret+=s[i]-'0',++i;
    return ret;
}

Elem parseTerm() {
    Elem ret;
    string name;
    if(s[i]=='('){
        ++i;
        ret=parseFormular();
        assert(s[i++]==')');
    }
    else{
        assert(upper(s[i]));
        name=parseElement();
        ++ret[name];
    }
    return ret;
}

Elem parseFormular() {
    Elem ret,term;
    int coef;
    while(true){
        term=parseTerm();
        if(digit(s[i])){
            coef=parseCoef();
        }
        else coef=1;
        for(auto& i:term) ret[i.first]+=coef*i.second;
        if(s[i]=='='||s[i]=='\0'||s[i]=='+'||s[i]==')')break;
    }
    return ret;
}

Elem parseExpr() {
    Elem ret,formular;
    int coef;
    while(true){
        if(digit(s[i])){
            coef=parseCoef();
        }
        else coef=1;
        formular=parseFormular();
        for(auto& i:formular) ret[i.first]+=coef*i.second;
        if(s[i]=='='||s[i]=='\0'){
            break;
        }
        if(s[i]=='+')++i;
    }
    return ret;
}

bool checkEquation() {
    Elem l,r;
    l=parseExpr();
    assert(s[i++]=='=');
    r=parseExpr();
    for(auto& i:l)fprintf(stderr,"%dx%s ",i.second,i.first.c_str());
    fprintf(stderr,"\n");
    for(auto& i:r)fprintf(stderr,"%dx%s ",i.second,i.first.c_str());
    fprintf(stderr,"\n");
    return l==r;
}

int main() {
    ios::sync_with_stdio(false),cin.tie(0);
#ifdef debug
    freopen("test.in","r",stdin);
#endif
    int n;
    cin>>n;
    cin.getline(s,sizeof(s));
    for(int _=0;_<n;++_){
        i=0;
        cin.getline(s,sizeof(s));
        fprintf(stderr,"eq: %s\n",s);
        printf("%c\n",checkEquation()?'Y':'N');
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值