CCF CSP认证 201912-3 化学方程式 (模拟/哈希) (100分)

 

 

 

检查化学方程式是否配平,没啥思维难度,硬着头皮模拟就行了,用栈记录当前的层数

第一种解法是纯模拟,用一个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

 

posted @ 2020-08-31 22:15  jrltx  阅读(478)  评论(0编辑  收藏  举报