csp 化学方程式被卡在90分,如果解决必有重赏

整体思想是创建两个map,分别记录=左边元素和右边元素,最终比较两边map计数是否相等,在=左边又通过+区分每个表达式,得到每个物质,insertmap函数就是在分解该物质。
初始就取出该物质的最开始的数字再进行处理。
总共考虑了四种情况:

  1. 为大写字母则判断后面是否为小写字母加入vector
  2. 左括号直接加入vector
  3. 右括号直接加入vector但是有可能右括号右边如果没有数字则插入一个数字1——原因在第四点
  4. 碰到数字,则判断数字签名是否为右括号,如果为右括号则通过vector向前遍历直到找到它对应的左括号,将这对括号内的元素全乘以这个数字,如果左边不是右括号,则只是将vector的最后一个元素乘以该数字

最后在将vector的内容放入对应map中

#include<bits/stdc++.h>
using namespace std;
struct node
{
    string s;
    int num;
    node(string a,int b){s=a;num=b;}
};
map<string,int>lefts;
map<string,int>rights;
int getnum(string s)
{
  int re=0;
  for(int i=0;i<s.size();i++)
  {
      re=re*10+s[i]-'0';
  }
  return re;
}
void insertmap(string t,bool flag)
{
    int index=0;
    int all=0;
    while(t[index]<='9'&&t[index]>='0')index++;
    if(index==0)all=1;
    else {
    string temp=t.substr(0,index);
    all=getnum(temp);
    }
    vector<node>q;
    //stack<node>q;
    for(int i=index;i<t.size();i++)
    {
       if(t[i]>='A'&&t[i]<='Z')
       {
           string tt;tt=t[i];
           if(t[i+1]>='a'&&t[i+1]<='z'&&i+1<t.size())
           {
             tt+=t[i+1]; i++;
           }
           q.push_back(node(tt,1));
       }
       else if(t[i]=='(')
            q.push_back(node("(",1));
       else if(t[i]==')')
       {
           if(i+1==t.size()||!isdigit(t[i+1]))
            t.insert(i+1,"1");
            q.push_back(node(")",1));
       }
       else if(t[i]<='9'&&t[i]>='0')
       {
           int index=i;
           while(t[index]>='0'&&t[index]<='9')
            index++;
           string tts=t.substr(i,index-i);
           int nums=getnum(tts);
           node tt=q[q.size()-1];
           if(tt.s==")")
           {
               q.pop_back();
               vector<node>::iterator it=q.end();
               while(it->s!="(")
               {
                   it->num*=nums;
                   it--;
               }
               q.erase(it);
           }
           else
           {
               q[q.size()-1].num*=nums;
           }
           i=index-1;
       }
    }
    while(!q.empty())
    {
        node t=q[q.size()-1];
        q.pop_back();
        if(!flag){lefts[t.s]+=t.num*all;}
        else {//cout<<t.s<<"**"<<t.num*all<<endl;
                rights[t.s]+=t.num*all;}
    }
}
bool isok()
{
    for(map<string,int>::iterator it=lefts.begin();it!=lefts.end();it++)
    {
        //cout<<it->first<<" "<<it->second<<" "<<rights[it->first]<<endl;
        if(rights[it->first]!=it->second)
            return false;
    }
    return true;
}
int main()
{
    int q;
    cin>>q;
    while(q--)
    {
        //³õʼ»¯map
        lefts.clear();
        rights.clear();
        string s;
        cin>>s;
        bool flag=false;//×ó±ß
        for(int i=0;i<s.size();i++)
        {
            int index=i;
            while(s[index]!='+'&&s[index]!='='&&index<s.size())
                index++;
            string temp=s.substr(i,index-i);
            insertmap(temp,flag);
            if(s[index]=='=')
             flag=true;
             i=index;
        }
        bool ok=isok();
       // for(map<string,int>::iterator it=lefts.begin();it!=lefts.end();it++)
           // cout<<it->first<<" "<<it->second<<endl;
       // for(map<string,int>::iterator it=rights.begin();it!=lefts.end();it++)
            //cout<<it->first<<" "<<it->second<<endl;
        if(ok)cout<<"Y"<<endl;
        else cout<<"N"<<endl;
    }
}
//2H2+O2=2H2O


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值