• Dark模拟的第一次尝试


    【解题报告】 P4711 「化学」相对分子质量

    虽然作为一道模拟题,但是毕竟是本人打出的第一道名副其实的模拟题,所以我在这里觉得有必要写一个博客来纪念一下。顺便总结一下一些模拟题的做法。

    题目传送门:P4711 「化学」相对分子质量

    但是我看到这道题的时候也是一脸懵逼,因为我想到这个化学式可能是括号套括号,所以当时因为这个问题我思考了好久,但是后来发现其实这根本是没有必要的,因为原子团中的括号只可能有一个,不可能套一堆上去,所以说当我们明白了这一点的时候,我们就又离成功近了一步,于是我们只需要整理一下思路进行下面的处理就可以了。

    1、首先我们发现的是化学式中有很多的数字信息等待我们去处理,所以说我们有必要写一个读入数字的程序,那么其实这个东西也是非常好写的,我们只需要往函数中读入第一个数字所在的位置,然后往后进行数,看下一位是不是数字,依次类推,直到不是数字我们就弹出循环,然后就可以了。这里不要忘了,我们传入当前化学式第i个位置寻找数字,那么寻找完毕后我们也应该同步更改化学式i的值,往后加。

    2、其次我们也发现化学式中有很多元素,所以我们也要对他进行处理,我们书写一个函数,当每次在主程序中找到一个大写字母后,进入函数,确定他的元素名称,并且利用上面第一个找数字的函数找到这个元素有几个,然后我们就可以算出这个元素的质量,然后用此函数进行返回就可以了。

    3、最后,让我们来解决一下最难的一个问题,就是当化学式中出现了原子团我们应该如何应对。应对方法如下:

    当我们找到一个“(”时表明我们找到了一个原子团,这个时候我们在主程序中嵌套一个找到“)”才停止的循环,再开一个临时的变量用于存放当前一个原子团的相对分子质量然后我们利用上面一样的思想,每当找到一个大写字母,我们就加上当前元素的相对原子质量,然后当我们碰到了“)”时,说明我们已经累加完了单个原子团的相对原子质量,然后我们判断一下后面有没有“——”东西,有的话,我们在调用找数字的函数,找出有几个原子团然后,把他累加到总质量上,就可以了。

    总而言之,我们如果想要打好模拟题,我们就要相办法把一个困难的问题分成很多很小且简单的问题,这样就可以了!

    这道题虽然难度标号非常的高,但是如果我们能够把复杂的问题简单化,其实还是非常的简单的。

    下面上一篇AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    map<string,double> ele;
    char ch[1003],b[15];
    void element()
    {
        ele["H"]=1;
        ele["C"]=12;
        ele["N"]=14;
        ele["O"]=16;
        ele["F"]=19;
        ele["Na"]=23;
        ele["Mg"]=24;
        ele["Al"]=27;
        ele["Si"]=28;
        ele["P"]=31;
        ele["S"]=32;
        ele["Cl"]=35.5;
        ele["K"]=39;
        ele["Ca"]=40;
        ele["Mn"]=55;
        ele["Fe"]=56;
        ele["Cu"]=64;
        ele["Zn"]=65;
        ele["Ag"]=108;
        ele["I"]=127;
        ele["Ba"]=137;
        ele["Hf"]=178.5;
        ele["Pt"]=195;
        ele["Au"]=197;
        ele["Hg"]=201;
    }
    int number(int &i)
    {
        int x=0;
        while(ch[i]>='0'&&ch[i]<='9')
        {
            x=x*10+(ch[i]-'0');
            i++;
        } 
        i--;
        return x;
    } 
    double name(int &i)
    {
        bool flag=false;
        memset(b,0,sizeof(b));
        int cnt=-1;
        while(((ch[i]>='A'&&ch[i]<='Z')||(ch[i]>='a'&&ch[i]<='z'))&&(cnt<0||(cnt>=0&&(ch[i]>='a'&&ch[i]<='z'))))
        {
            flag=true;
            cnt++;
            b[cnt]=ch[i];
            i++;
        }
        if(ch[i]=='_')
        {
            i=i+2;
            int count=number(i);
            return count*ele[b];
        }
        else
        {
            if(flag) i--;
            return ele[b];
        }
    }
    int main()
    {
        double s,k;s=0; 
        element();
        cin.getline(ch,1003);
        int sk=strlen(ch);
        for(int i=0;i<sk;++i)
        {
            if(ch[i]>='A'&&ch[i]<='Z')
             s+=name(i);
            if(ch[i]=='(')
            {
                double sum; sum=0;
                i++;
                for(k=0;ch[i]!=')';i++)
                k+=name(i);
                if(ch[i+1]=='_')
                i=i+3;
                s+=k*number(i); 
            }
            if(ch[i]=='~')
            {
                i++;
                if(ch[i]=='H')
                s+=18.0;
                else
                {
                    s+=number(i)*18.0;
                }
                break;
            }
        } 
        printf("%g",s);
        return 0;
    } 
    

    谢谢采纳!

  • 相关阅读:
    小猪存钱罐
    SSL与HTTPS协议
    KVM之XFS磁盘扩容
    vue学习笔记(一)
    ant打包总结
    github上传代码总结
    java中map遍历的总结
    angularjs初学总结
    angularjs常用指令
    github上传代码总结
  • 原文地址:https://www.cnblogs.com/mudrobot/p/13330704.html
Copyright © 2020-2023  润新知