检查化学方程式是否配平,没啥思维难度,硬着头皮模拟就行了,用栈记录当前的层数
第一种解法是纯模拟,用一个map记录元素种类和每种元素的个数,比较麻烦但容易debug(复杂度:??有点玄学):
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e3+10; 5 typedef vector<string> Vec; 6 typedef map<string,int> Map; 7 Map operator*(Map a,int x) {for(auto& t:a)t.second*=x; return a;} 8 Map operator+(Map a,Map b) { 9 for(auto t:b)a[t.first]+=t.second; 10 return a; 11 } 12 bool operator==(Map a,Map b) { 13 if(a.size()!=b.size())return 0; 14 for(auto t:b)if(!a.count(t.first)||a[t.first]!=t.second)return 0; 15 return 1; 16 } 17 Map F(string s) {Map a; a[s]=1; return a;} 18 Vec split(string S,char C) { 19 Vec vec; 20 string s; 21 for(char c:S) { 22 if(c==C)vec.push_back(s),s.clear(); 23 else s.push_back(c); 24 } 25 vec.push_back(s); 26 return vec; 27 } 28 int n,tp,dep[N]; 29 Map sta[N]; 30 Map solve(string s) { 31 tp=0; 32 int i=0,x=0,d=0; 33 for(; i<s.length()&&isdigit(s[i]); ++i)x=x*10+s[i]-'0'; 34 if(x==0)x=1; 35 for(; i<s.length(); ++i) { 36 if(isupper(s[i])) { 37 string t; 38 if(i+1<s.length()&&islower(s[i+1]))t=string(1,s[i])+string(1,s[i+1]),++i; 39 else t=string(1,s[i]); 40 sta[tp]=F(t),dep[tp++]=d; 41 } else if(isdigit(s[i])) { 42 int y=0; 43 for(; i<s.length()&&isdigit(s[i]); ++i)y=y*10+s[i]-'0'; 44 sta[tp-1]=sta[tp-1]*y; 45 --i; 46 } else if(s[i]=='(') { 47 ++d; 48 } else if(s[i]==')') { 49 Map t; 50 for(; tp&&dep[tp-1]==d; --tp)t=t+sta[tp-1]; 51 --d; 52 sta[tp]=t,dep[tp++]=d; 53 } 54 } 55 Map t; 56 for(; tp&&dep[tp-1]==d; --tp)t=t+sta[tp-1]; 57 return t*x; 58 } 59 Map solve2(string s) { 60 Vec vec=split(s,'+'); 61 Map t; 62 for(string ss:vec)t=t+solve(ss); 63 return t; 64 } 65 int main() { 66 cin>>n; 67 while(n--) { 68 string s; 69 cin>>s; 70 Vec vec=split(s,'='); 71 Map mp1=solve2(vec[0]); 72 Map mp2=solve2(vec[1]); 73 puts(mp1==mp2?"Y":"N"); 74 } 75 return 0; 76 }
还有一种解法是利用哈希,方法有很多种,不再细说了,代码较为简单但不好debug(复杂度O(n),巨快,如果map被卡时间的话可以改写成这个):
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned long long ll; 4 const int N=1e3+10,M=19260817; 5 typedef vector<string> Vec; 6 ll H2(ll x) {return x^=x<<12,x^=x>>7,x^=x<<13;} 7 ll H(ll x) {return H2(H2(H2(x)));} 8 Vec split(string S,char C) { 9 Vec vec; 10 string s; 11 for(char c:S) { 12 if(c==C)vec.push_back(s),s.clear(); 13 else s.push_back(c); 14 } 15 vec.push_back(s); 16 return vec; 17 } 18 int n,tp,dep[N]; 19 ll sta[N]; 20 ll solve(string s) { 21 tp=0; 22 int i=0,x=0,d=0; 23 for(; i<s.length()&&isdigit(s[i]); ++i)x=x*10+s[i]-'0'; 24 if(x==0)x=1; 25 for(; i<s.length(); ++i) { 26 if(isupper(s[i])) { 27 ll t=0; 28 if(i+1<s.length()&&islower(s[i+1]))t=H(s[i]*M+s[i+1]),++i; 29 else t=H(s[i]); 30 sta[tp]=t,dep[tp++]=d; 31 } else if(isdigit(s[i])) { 32 int y=0; 33 for(; i<s.length()&&isdigit(s[i]); ++i)y=y*10+s[i]-'0'; 34 sta[tp-1]=sta[tp-1]*y; 35 --i; 36 } else if(s[i]=='(') { 37 ++d; 38 } else if(s[i]==')') { 39 ll t=0; 40 for(; tp&&dep[tp-1]==d; --tp)t=t+sta[tp-1]; 41 --d; 42 sta[tp]=t,dep[tp++]=d; 43 } 44 } 45 ll t=0; 46 for(; tp&&dep[tp-1]==d; --tp)t=t+sta[tp-1]; 47 return t*x; 48 } 49 ll solve2(string s) { 50 Vec vec=split(s,'+'); 51 ll t=0; 52 for(string ss:vec)t=t+solve(ss); 53 return t; 54 } 55 int main() { 56 cin>>n; 57 while(n--) { 58 string s; 59 cin>>s; 60 Vec vec=split(s,'='); 61 ll mp1=solve2(vec[0]); 62 ll mp2=solve2(vec[1]); 63 puts(mp1==mp2?"Y":"N"); 64 } 65 return 0; 66 }
样例:
1 11 2 H2+O2=H2O 3 2H2+O2=2H2O 4 H2+Cl2=2NaCl 5 H2+Cl2=2HCl 6 CH4+2O2=CO2+2H2O 7 CaCl2+2AgNO3=Ca(NO3)2+2AgCl 8 3Ba(OH)2+2H3PO4=6H2O+Ba3(PO4)2 9 3Ba(OH)2+2H3PO4=Ba3(PO4)2+6H2O 10 4Zn+10HNO3=4Zn(NO3)2+NH4NO3+3H2O 11 4Au+8NaCN+2H2O+O2=4Na(Au(CN)2)+4NaOH 12 Cu+As=Cs+Au