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;
}