zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    linux下配置java环境及问题
    Chrome工具使用
    Ibatis的resultMap和查询数据的对应关系
    spring mvc接收数组
    PowderDesign的使用
    Android Runtime Stats
    [原创]ASM动态修改JAVA函数之函数字节码初探
    [原创]WB Android客户端架构总结:发WB工作队列设计
    [原创]Android Studio的Instant Run(即时安装)原理分析和源码浅析
    [原创]Android系统中常用JAVA类源码浅析之HashMap
  • 原文地址:https://www.cnblogs.com/asdfsag/p/13592309.html
Copyright © 2011-2022 走看看