原题链接:CSP 201912-3 化学方程式
自己写的40分代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6;
int n;
struct node
{
string s;
int num;
node(string _s,int _num)
{
s=_s;
num=_num;
}
};
map<string,int> m;
void fun1(string str,int f)
{
int i=0;
int num=1;
for(;i<str.size();)
{
if(str[i]>='0'&& str[i]<='9')
i++;
else
break;
}
if(i>0)
{
string t=str.substr(0,i+1);
num=atoi(t.c_str());
}
for(;i<str.size();)
{
if(str[i]>='A'&& str[i]<='Z')//当前为大写
{
int tmp=1;string t;
if(i<str.size()-1 && str[i+1]>='0'&& str[i+1]<='9')//后一个为数字
{
t=str.substr(i,1);
tmp=int(str[i+1]-'0');
i+=2;
}
else if(i<str.size()-1 && str[i+1]>='A'&& str[i+1]<='Z')//后一个为大写
{
t=str.substr(i,1);
i+=1;
}
else if(i==str.size()-1)//最后一个
{
t=str.substr(i,1);
i++;
}
else if(i<str.size()-1 && str[i+1]>='a'&& str[i+1]<='z')//后一个为小写
{
t=str.substr(i,2);
if(i<str.size()-2 && str[i+2]>='0'&& str[i+2]<='9')//小写后有数字
{
tmp=int(str[i+2]-'0');
i+=3;
}
else
i+=2;//小写后没有数字
}
int tnum=tmp*num;
if(f)
m[t]+=tnum;
else
m[t]-=tnum;
}
}
}
void fun2(string str,int f)
{
int l=0,len=0;
for(int i=0;i<str.size();i++)
{
if(str[i]!='+')
{
len++;
}
if(str[i]=='+' || i==str.size()-1)
{
string tmp=str.substr(l,len);
//cout<<tmp<<" "<<endl;
fun1(tmp,f);
l=l+len+1;
len=0;
}
}
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0); std::cout.tie(0);
cin>>n;
while(n--)
{
m.clear();
string str;
cin>>str;
int pos=str.find("=");
string s1=str.substr(0,pos);
string s2=str.substr(pos+1);
fun2(s1,1);
fun2(s2,0);
int flag=1;
for(map<string,int>::iterator it=m.begin();it!=m.end();it++)
{
//cout<<it->first<<" "<<it->second<<endl;
if(it->second!=0)
{
cout<<"N"<<endl;
flag=0;
break;
}
}
if(flag)
cout<<"Y"<<endl;
}
return 0;
}
参考别人的100分代码:CCF计算机软件能力认证试题练习:201912-3 化学方程式
#include<bits/stdc++.h>
using namespace std;
int n;
struct node
{
string s;
int num;
node(string _s,int _num)
{
s=_s;
num=_num;
}
};
int tonumber(string str,int &pos)
{
int num=0;
while(isdigit(str[pos]))
{
num=num*10+str[pos]-'0';
pos++;
}
return num;
}
void cal(string &str,map<string,int> &mp)
{
stringstream ss(str);
string item;
while(getline(ss,item,'+'))
{
vector<node> a;
int factor=1;
int i=0;
if(isdigit(item[i]))
{
factor=tonumber(item,i);
}
while(i<item.size())
{
if(isdigit(item[i]))
{
int num=tonumber(item,i);
if(a[a.size()-1].s==")")
{
int j=a.size()-1;
a[j].s="*";
while(a[--j].s!="(")
a[j].num*=num;
a[j].s="*";
}
else
a[a.size()-1].num*=num;
}
else if(item[i]=='(')
{
a.push_back(node("(",0));
i++;
}
else if(item[i]==')')
{
a.push_back(node(")",0));
if(i+1==item.size() || !isdigit(item[i+1]))
item.insert(i+1,"1");
i++;
}
else if(isupper(item[i]))
{
string name="";
name+=item[i];
i++;
if(islower(item[i]))
{
name+=item[i];
i++;
}
a.push_back(node(name,1));
}
}
for(int i=0;i!=a.size();i++)
{
if(a[i].s=="*")
continue;
mp[a[i].s]+=(a[i].num*factor);
}
}
}
bool judge(map<string,int> &l,map<string,int> &r)
{
if(l.size()!=r.size())
return false;
for(map<string,int>::iterator it=l.begin();it!=l.end();it++)
{
if(r[it->first]!=it->second)
return false;
}
return true;
}
int main()
{
std::ios::sync_with_stdio(false);
cin>>n;
while(n--)
{
map<string,int> l,r;
string str,s1,s2;
cin>>str;
stringstream ss(str);
getline(ss,s1,'=');
getline(ss,s2);
cal(s1,l);
cal(s2,r);
if(judge(l,r))
cout<<"Y"<<endl;
else
cout<<"N"<<endl;
}
return 0;
}
80分代码(没有处理括号嵌套的情况)
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
map<string,int> cal(string s)
{
vector<string> v;
string t;
stringstream ss(s);
while(getline(ss,t,'+')) v.push_back(t);
map<string,int> mp;
for(auto tmp:v)
{
int i=0,num=1;
while(isdigit(tmp[i])) i++;
t=tmp.substr(0,i);
if(i>0) num=atoi(t.c_str());
for(;i<tmp.size();)
{
if(isupper(tmp[i]))
{
int cnt=1;
t=""; t+=tmp[i];
if(i+1<tmp.size() && islower(tmp[i+1]))
{
t+=tmp[i+1];
i++;
}
if(i+1<tmp.size() && isdigit(tmp[i+1]))
{
i++; int start=i;
while(i<tmp.size() && isdigit(tmp[i])) i++;
string tt=tmp.substr(start,i-start);
cnt=atoi(tt.c_str());
}
else i++;
mp[t]+=(cnt*num);
}
else if(tmp[i]=='(')
{
int j=i,total=1;
while(tmp[j]!=')') j++;
t=""; j++;
while(j<tmp.size() && isdigit(tmp[j]))
{
t+=tmp[j];
j++;
}
if(t!="") total=atoi(t.c_str());
i++;
while(tmp[i]!=')')
{
if(isupper(tmp[i]))
{
int cnt=1;
t=""; t+=tmp[i];
if(i+1<tmp.size() && islower(tmp[i+1]))
{
t+=tmp[i+1];
i++;
}
if(i+1<tmp.size() && isdigit(tmp[i+1]))
{
i++; int start=i;
while(i<tmp.size() && isdigit(tmp[i])) i++;
string tt=tmp.substr(start,i-start);
cnt=atoi(tt.c_str());
}
else i++;
mp[t]+=(cnt*total*num);
}
}
i=j;
}
}
}
return mp;
}
bool judge(string s1,string s2)
{
map<string,int> mp1=cal(s1);
map<string,int> mp2=cal(s2);
return mp1==mp2;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n; cin>>n;
while(n--)
{
string s;
cin>>s;
int i=0;
while(s[i]!='=') i++;
string s1=s.substr(0,i);
string s2=s.substr(i+1);
if(judge(s1,s2)) cout<<"Y"<<endl;
else cout<<"N"<<endl;
}
return 0;
}
测试样例
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
Cu+As=Cs+Au
4Au+8NaCN+2H2O+O2=4Na(Au(CN)2)+4NaOH