B 分子

题目描述 在遥远的斯卡布罗集市,有机分子只能由 C, H, O 三种元素组成。根据珂学家们的探测,一个 C 原子的式量为 13 ,一个 H 原子的式量为 1 ,一个 O 原子的式量为 17 。一个有机分子的式量恰为各个原子的式量的总和。对于有机分子式给出如下定义:有机分子式只可能包含数字、括号和 C, H, O 三种元素标记;数字只能出现在元素标记或右括号的右边,代表该元素(或括号内的分子式)重复出现的次数;数字只可以是不包含前导零的正整数;如果一个元素右侧没有数字,那么表示该元素只出现一次;括号内包含非空的有机分子式,但该有机分子式不再嵌套括号。例如 (HH)3H(H)、CO2、CH12、CHHOO 都是合法的有机分子式。而 4HC、CHTHOLLOY、CH3(CH2)3(CH(CHCH3)2CH3)2(CH2)3CH3 都不是合法的有机分子式。对于符合上述要求的分子式,你能帮助珂学家们计算它的分子式量吗?

输入描述 输入仅一行,包含一个字符串,代表分子式。保证符合上述定义,字符串中不含除 C, H ,O,括号和数字以外的字符,且长度不超过 10^5

输出描述 在一行中输出一个整数,代表该分子的式量。保证答案不超过 10^15。

思路
我原本还以为这道题和栈的经典应用题型“解析计算式”相近,没想到这题还更简单,因为题目里说了没有嵌套括号,所以这题都不用开栈。
考虑把括号内的权重单独算,然后把整个括号看作一个整体元素,那么这题所给的分子式实际上就是由 元素 + 数量 的格式文本拼凑而成的。因此,我们每读入一个“元素”,就判断它后面是数字还是另一个元素符号,如果是数字,就读取这个数字,然后对应调整ans即可。
特别的,如果当前是在括号内,那么我们不能直接调整ans,而是要单独加到一个临时int变量中,直到遇到一个 ) 字符,再看 ) 字符后是数字还是其他符号。如果是数字,要把整个括号内的权重拿出来乘上这个数字加入ans,否则直接加到ans就行了。记得处理完后把这个临时int变量置零就好。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<iostream>
#include<cstring>
using namespace std;
template<class _T>inline void read(_T &_a)
{
    bool f=0; char _c=getchar(); _a=0;
    while(_c<'0'||_c>'9'){ if(_c=='-') f=1; _c=getchar(); }
    while(_c>='0'&&_c<='9'){ _a=(_a<<3)+(_a<<1)-'0'+_c; _c=getchar(); }
    if(f) _a=-_a;
}

const int MAXN=1000002;
char str[MAXN];
int n;
long long ans,tmpkh,tmpqz; // tmpkh临时储存了当前括号内的值,tmpqz用于读取数字。
bool inkh; // 在括号内

inline long long rd(int pos)
{
    long long _a=0;
    char _c=str[pos++];
    while(_c<'0'||_c>'9') _c=str[pos++];
    while(_c>='0'&&_c<='9'){ _a=(_a<<3)+(_a<<1)-'0'+_c; _c=str[pos++]; }
    return _a;
}

int main()
{
    scanf("%s",str+1);
    n=strlen(str+1);
    for (int i=1;i<=n;++i)
    {
        if(str[i]=='(')
        {
            inkh=true;
            continue;
        }
        if(str[i]==')')
        {
            inkh=false;
            if(str[i+1]>='0'&&str[i+1]<='9')
            {
                tmpqz=rd(i+1);
                ans+=tmpkh*tmpqz;
                while(str[i+1]>='0'&&str[i+1]<='9') ++i;
                tmpkh=0;
                continue;
            } else {
                ans+=tmpkh;
                tmpkh=0;
                continue;
            }
        }
        if(str[i]=='C')
        {
            if(inkh)
            {
                if(str[i+1]>='0'&&str[i+1]<='9')
                {
                    tmpqz=rd(i+1);
                    tmpkh+=13*tmpqz;
                    while(str[i+1]>='0'&&str[i+1]<='9') ++i;
                    continue;
                } else {
                    tmpkh+=13;
                    continue;
                }
            } else {
                if(str[i+1]>='0'&&str[i+1]<='9')
                {
                    tmpqz=rd(i+1);
                    ans+=13*tmpqz;
                    while(str[i+1]>='0'&&str[i+1]<='9') ++i;
                    continue;
                } else {
                    ans+=13;
                    continue;
                }
            }
        }
        if(str[i]=='H')
        {
            if(inkh)
            {
                if(str[i+1]>='0'&&str[i+1]<='9')
                {
                    tmpqz=rd(i+1);
                    tmpkh+=tmpqz;
                    while(str[i+1]>='0'&&str[i+1]<='9') ++i;
                    continue;
                } else {
                    tmpkh+=1;
                    continue;
                }
            } else {
                if(str[i+1]>='0'&&str[i+1]<='9')
                {
                    tmpqz=rd(i+1);
                    ans+=tmpqz;
                    while(str[i+1]>='0'&&str[i+1]<='9') ++i;
                    continue;
                } else {
                    ans+=1;
                    continue;
                }
            }
        }
        if(str[i]=='O')
        {
            if(inkh)
            {
                if(str[i+1]>='0'&&str[i+1]<='9')
                {
                    tmpqz=rd(i+1);
                    tmpkh+=17*tmpqz;
                    while(str[i+1]>='0'&&str[i+1]<='9') ++i;
                    continue;
                } else {
                    tmpkh+=17;
                    continue;
                }
            } else {
                if(str[i+1]>='0'&&str[i+1]<='9')
                {
                    tmpqz=rd(i+1);
                    ans+=17*tmpqz;
                    while(str[i+1]>='0'&&str[i+1]<='9') ++i;
                    continue;
                } else {
                    ans+=17;
                    continue;
                }
            }
        }
    }
    printf("%lld",ans);
    return 0;
}
©著作权归作者所有

发表评论

正在加载 Emoji