zoukankan      html  css  js  c++  java
  • HUNNU11342:Chemistry(模拟)

    http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=11342

    Problem description

      

    The chemical formula of a molecule M describes its atomic make-up. Chemical formulas obey the following grammar:

          M := G | M G
          G := S | S C
          S := A | '(' M ')'
          C := T | N E
          E := D | D E
          T := '2' | ... | '9'
          N := '1' | ... | '9'
          D := '0' | .. | '9'
          A := U | U L | U L L 
          U := 'A' | .. | 'Z'
          L := 'a' | .. | 'z'
        

    The count C represents a multiplier for the subgroup S that precedes it. For example, H2O has two H (hydrogen) and one O (oxygen) atoms, and (AlC2)3Na4 contains 3 Al (aluminum), 6 C (carbon) and 4 Na (sodium) atoms.

    Input
      The input will contain data for one or more test cases. For each test case, there will be one line of input, containing a valid chemical formula. Each line will have no more than 100 characters. 
    Output
      For each line of input there will be one line of output which is the atomic decomposition of the chemical in the form of a sum as shown in the sample output. The atoms are listed in lexicographical order, and a count of 1 is implied and not explicitly written. There are no blank spaces in the output. All of the counts in the correct output will be representable in 32-bit signed integers. 
    Sample Input
    H2O
    (AlC2)3Na4
    Sample Output
    2H+O
    3Al+6C+4Na
    Problem Source

      2012 Rocky Mountain Regional Contest

    题意:按字典序升序输出所有元素

    思路:一道恶心的模拟题啊,暴力模拟即可,弄了好久啊,一开始是全部算出来在进行叠加,但是超时了,于是就每次计算完一个元素后都放进去,终于过了,0ms

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    
    struct node
    {
        char word[105];
        int cnt;
    } a[105];
    
    char str[105];
    
    int cmp(node x,node y)
    {
        return strcmp(x.word,y.word)<0;
    }
    
    int main()
    {
        while(~scanf("%s",str))
        {
            int len = strlen(str),flag = 1;
            int l = -1,ll = 0;
            int i,j,k,zuo,t;
            for(i = 0; i<=100; i++)
                memset(a[i].word,'',sizeof(a[i].word));
            for(i = 0; i<len; i++)
            {
                if(str[i]>='A' && str[i]<='Z')
                {
                    if(l!=-1)
                        a[l].word[ll] = '';
                    flag = 1;
                    ll = 0;
                    if(l!=-1)
                    {
                        int tt = 0,c;
                        for(j = k; j<len; j++)//从该元素往后走,找括号
                        {
                            if(str[j] == '(')//找左括号
                                tt++;
                            else if(str[j] == ')')
                            {
                                if(tt)//与左括号匹配,消去一个无用的右括号
                                    tt--;
                                else
                                {
                                    zuo--;//匹配包含该元素的左括号
                                    j++;
                                    c = 0;
                                    while(str[j]>='0' && str[j]<='9')//计算括号后面的数字
                                    {
                                        c = c*10+str[j]-'0';
                                        j++;
                                    }
                                    j--;
                                    if(c)//非0则与原来的数字相乘
                                    a[l].cnt*=c;
                                }
                            }
                            if(!zuo)//没有包含该元素的左括号则跳出
                                break;
    
                        }
                    }
                    for(j = 0; j<l; j++)
                    {
                        if(!strcmp(a[j].word,a[l].word))//有与该元素匹配的就直接将该元素的数目累加,并且长度减1,没有则不管
                        {
                            a[j].cnt+=a[l].cnt;
                            l--;
                            break;
                        }
                    }
                    l++;//下一个元素
                    a[l].word[ll++] = str[i];//放进结构体
                    k = i;//记录位置
                    a[l].cnt = 1;//初始化个数为1
                    t = zuo = 0;
                    for(j = i; j>=0; j--)//记录左边将此元素包裹在内的左括号的数量
                    {
                        if(str[j] == ')')
                            t++;
                        else if(str[j] == '(')
                        {
                            if(t)
                                t--;
                            else
                                zuo++;
                        }
                    }
                }
                else if(str[i]>='a' && str[i]<='z')
                    a[l].word[ll++] = str[i];
                else if(str[i]>='0' && str[i]<='9' && flag && (str[i-1]>='A' && str[i-1]<='Z' || str[i-1]>='a' && str[i-1]<='z') )
                {//这条件很重要,这是计算紧跟在元素后的数字,但不能算括号后面的数字
                    flag = 0;
                    int c = 0;
                    while(str[i]>='0' && str[i]<='9')
                    {
                        c = c*10+str[i]-'0';
                        i++;
                    }
                    i--;
                    if(c)
                        a[l].cnt*=c;
                }
            }
            while(zuo)//这是计算最后一个元素,因为最后一个元素可能没有算
            {
                int tt = 0,c;
                for(j = k; j<len; j++)
                {
                    if(str[j] == '(')
                        tt++;
                    else if(str[j] == ')')
                    {
                        if(tt)
                            tt--;
                        else
                        {
                            zuo--;
                            j++;
                            c = 0;
                            while(str[j]>='0' && str[j]<='9')
                            {
                                c = c*10+str[j]-'0';
                                j++;
                            }
                            j--;
                            if(c)
                            a[l].cnt*=c;
                        }
                    }
                }
            }
            for(j = 0; j<l; j++)
            {//医务室计算最后一个元素
                if(!strcmp(a[j].word,a[l].word))
                {
                    a[j].cnt+=a[l].cnt;
                    l--;
                    break;
                }
            }
            sort(a,a+l+1,cmp);
            if(a[0].cnt!=1)
                printf("%d%s",a[0].cnt,a[0].word);
            else
                printf("%s",a[0].word);
            for(i = 1; i<=l; i++)
            {
                if(a[i].cnt!=1)
                    printf("+%d%s",a[i].cnt,a[i].word);
                else
                    printf("+%s",a[i].word);
            }
            printf("
    ");
        }
    
        return 0;
    }
    


     

  • 相关阅读:
    java 使用jsch 远程链接linux执行命令
    Scott Mitchell 的ASP.NET 2.0数据教程之十三:在DetailsView控件中使用TemplateField
    Scott Mitchell 的ASP.NET 2.0数据教程之二十二:为删除数据添加客户端确认
    左边有个treeviwe控件,点击tree控件的一个节点右面进入相应的网页
    Scott Mitchell 的ASP.NET 2.0数据教程之二十三:基于用户对修改数据进行限制
    Scott Mitchell 的ASP.NET 2.0数据教程之十九:给新增、编辑界面增加验证控件 (翻译)
    Scott Mitchell 的ASP.NET 2.0数据教程之十二:在GridView控件中使用TemplateField
    Scott Mitchell 的ASP.NET 2.0数据教程之二十定制数据修改界面
    Scott Mitchell 的ASP.NET 2.0数据教程之十四:使用FormView 的模板
    Scott Mitchell 的ASP.NET 2.0数据教程之二十一:: 实现开放式并发
  • 原文地址:https://www.cnblogs.com/pangblog/p/3292242.html
Copyright © 2011-2022 走看看