甘肃传媒大学第七届程序设计大赛

“波导杯”浙江财经政法大学第七届程序设计大赛

原著作网页

Contest – 2016 “Bird Cup” ICPC7th@ahstu

Start time:  2016-04-23 08:00:00.0  End time:  2016-04-23 12:00:00.0
Current System Time:  2016-04-23 19:02:17.554  Contest Status:   Ended

关于设立“波导杯”海南矿业高校第七届程序设计大赛通告

ACM 国际硕士程序设计比赛 (International Collegiate Programming
Contest)是由花旗国总括机协会(ACM)主办的一项意在展现研究生立异能力、团队精神和在压力下编写程序、分析和化解问题能力的出名竞赛。二零一零年以来,我校参加了历届甘肃省 ACM 程序设计比赛,并拿走了出色的成绩。为遴选校 ACM 参赛队员,将设立“波导杯” 黑龙江财经政法大学第七届总括机程序设计大赛,热忱欢迎广大程序设计爱好者踊跃插足。

主办方:河北交通大学教务处、信息与网络工程高校

承办方:新闻与网络工程高校

赞助方:麦迪逊波导软件有限公司(独家赞助)

一、 比赛时间:2016 年 4 月23(周六)上午 8:00~12:00

二、竞赛地点:总计机与网络试验中央(力行楼六楼)

三、比赛设奖:设一等奖8%、二等奖12%、三等奖15%。

六、比赛相关:

比赛语言:C/C++/JAVA 环境:DevCpp /CodeBlock /Eclipse

比赛试题:选取 ICPC 样式——赛题 8~10道

注意事项:

·  1. 练兵比赛网站(安科 OJ):http://183.167.205.82:8081/JudgeOnline/

·  2. 电脑系 ACM/ICPC 学生活动室位于力行楼六楼,欢迎交换。

竞技 QQ 群:173592864(波导杯第七届校ACM赛)

Problem Id Title
1366 Problem A Dotaer vs Loler
1367 Problem B so so so easy
1368 Problem C 反转链表
1369 Problem D 贪吃蛇
1370 Problem E 均分硬币
1371 Problem F 丢啊丢啊丢手绢
1372 Problem G 分糖果
1373 Problem H 埋炸弹啦~
1374 Problem I 化学老师的惩罚
1375 Problem J 水题!

[Standings]  [Status]  [Statistics]

Dotaer vs Loler


Time Limit:1000MS Memory Limit:65536K
Total Submit:170 Accepted:31

Description

小杨是一名Dota资深玩家,和许多Dota玩家一样,他和四礼拜日群LOL玩家在联名有一种自然的优越感,但是身边的刀友确一个个投入了撸狗的队列,直到现在周围再没了
一个同行。。。他很气愤,于是有了下面这道问题:
两个分别只包含Dotaer和Loler中的字母的字符串,长度(<10^6),请你分别总结六个字符串中所含字母可以整合Dotaer和Loler的最大数目(不区分轻重缓急写),然后根
据两者的数目判断输赢,若Loler数量大于Dotaer数量的3倍,则Loler
win,反之Dotaer win。

Input

各类输入包含五个测试用例,每个测试用席卷两行,第一行事结合Dotaer的字符串,第二行事构成Loler的字符串。

Output

对此每个测试用例输出三行,第一行事Dotaer数量,第二行事Loler数量,第三行事哪方win。

Sample Input

otdarrreoddtooaaoooee
rolereoreolrereoreol

Sample Output

Dotaer: 2
Loler: 1
Dotaer win

化学方程式,Source

icpc7th@ahstu

#include<iostream>
#include<string>
#include<map>
#include<fstream>
using namespace std;
map<char,int>Dota;
map<char,int>LOL;
map<char,int>::iterator d_it;
map<char,int>::iterator l_it;
char change(char a)
{
   return (a<97)?(a+32):a;
}
void print()
{
    for(d_it=LOL.begin();d_it!=LOL.end();d_it++)
    {
        cout<<d_it->second<<" "<<d_it->first<<endl;
    }
}
int dota(string D)
{
    for(int i=0;i<D.size();i++)
    {
        Dota[change(D[i])]++;
    }
    Dota['d'];Dota['o'];
    Dota['t'];Dota['a'];
    Dota['e'];Dota['r'];
    int m=1000001;
   for(d_it=Dota.begin();d_it!=Dota.end();d_it++)
   {
       if(m>(d_it->second))
        m=(d_it->second);
   }
   return m;
}
int lol(string L)
{
     for(int i=0;i<L.size();i++)
    {
        LOL[change(L[i])]++;
    }
    LOL['l']; LOL['o'];
    LOL['e']; LOL['r'];
    int m=1000001;
    for(l_it=LOL.begin();l_it!=LOL.end();l_it++)
    {
        if((l_it->first)!='l')
        {
            if(m>(l_it->second))
                m=l_it->second;
        }
        else
        {
            if(m>(l_it->second)/2)
                m=(l_it->second)/2;
        }
    }
    return m;
}
int main()
{
    //freopen("Dotaer vs Loler.in","r",stdin);
    //freopen("Dotaer vs Loler.out","w",stdout);
    string D,L;
    int D_num,L_num;
    while(cin>>D>>L)
    {
       D_num=dota(D);
       L_num=lol(L);
       cout<<"Dotaer: "<<D_num<<endl;
       cout<<"Loler: "<<L_num<<endl;
       if(L_num>3*D_num)
        cout<<"Loler win"<<endl;
       else
       cout<<"Dotaer win"<<endl;
       Dota.clear();
       LOL.clear();
    }
    return 0;
}

so so so easy


Time Limit:1000MS Memory Limit:65536K
Total Submit:46 Accepted:14

Description

为了防止打光头的图景出现,仁慈的老赵在每一次竞技中总会想尽的加水题进去,一个多少个两个…..。
幸存一个通通由被空格所分开的英文单词构成的字符串(单词数量<=100),请您数出每个单词是连接第一遍出现。(例如
so so so easy 结果为 1 2 3 1)

Input

各种输入包含四个测试用例,每个测试用例为一个全然由被空格所分开的英文单词构成的字符串。

Output

对此每个测试用例,输出其每个单词是接二连三第一遍面世。

Sample Input

so so so easy so so

Sample Output

1 2 3 1 1 2

Source

icpc7th@ahstu

#include<iostream>
#include<string>
#include<fstream>
#include<sstream>
using namespace std;
void easy(string A)
{
    int i;
    int num=0;
    string flag;
    string B[100];
    istringstream sin(A);
    for(i=0;sin>>B[i];i++);
    flag="";
    for(int j=0;j<i;j++)
    {
        if(B[j]!=flag)
        {
            num=1;
            flag=B[j];
            cout<<num<<" ";
        }
        else
        {
            num++;
            cout<<num<<" ";
        }
    }
    cout<<endl;
}
int main()
{
   // freopen("so so so easy.in","r",stdin);
   // freopen("so so so easy.out","w",stdout);
    string A;
    while(getline(cin,A))
    {
        easy(A);
    }
    return 0;
}

反转链表


Time Limit:1000MS Memory Limit:65536K
Total Submit:5 Accepted:0

Description

给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转。例如:给定L为1→2→3→4→5→6,K为3,则输出应该为3→2→1→6→5→4;假若K为4,则输出应该为4→3→2→1→5→6,即最终不到K个元素不反转。

Input

每个输入包含五个测试用例。每个测试用例第1行提交第1个结点的地点、结点总个数正整数N(<=
105)、以及正整数K(<=N),即要求反转的子链结点的个数。结点的地方是5位非负整数,NULL地址用-1意味着。

接下去有N行,每行格式为:

Address Data Next

内部Address是结点地址,Data是该结点保存的平头数据,Next是下一结点的地址。

Output

对各样测试用例,顺序输出反转后的链表(每个节点的 Address Data
Next),其上各种结点占一行,格式与输入相同。

Sample Input

00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

Sample Output

00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1

Source

icpc7th@ahstu

    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<stdio.h>
    #include<cstdlib>
    #include<fstream>
    using namespace std;

    typedef struct
    {
        int add;
        int data;
        int next;
    }Node;
    Node L[100001];
    vector<Node>N;
    vector<Node>::iterator it;
    int scan(int &Add,int &num,int &n)
    {
        Node N;
        for(int i=0;i<num;i++)
        {
            cin>>N.add>>N.data>>N.next;
            L[N.add]=N;
        }
        return 1;
    }
    void L_sort(int start,int n)
    {
         int flag=start;
         while(flag!=-1)
         {
             N.push_back(L[flag]);
             flag=L[flag].next;
         }
    }
    void F_sort(int n)
    {
        int G=N.size()/n;
        for(int i=0;i<G;i++)
        {
            reverse((N.begin()+i*n),(N.begin()+(i+1)*n));
        }
    }
    void print()
    {
        for(it=N.begin();it<N.end()-1;it++)
        {
            printf("%05d %d %05d\n",(*it).add,(*it).data,(*(it+1)).add);
        }
                printf("%05d %d -1\n",(*(N.end()-1)).add,(*(N.end()-1)).data);
    }
    int main()
    {
       int Add,num,n;
        //freopen("反转链表.in","r",stdin);
        //freopen("反转链表.out","w",stdout);
        while(cin>>Add>>num>>n)
        {
            scan(Add,num,n);
           L_sort(Add,n);
           F_sort(n);
           print();
           N.clear();
        }
        return 0;
    }

贪吃蛇


Time Limit:1000MS Memory Limit:65536K
Total Submit:9 Accepted:2

Description

有小儿的男女都玩过这些经典游戏,不过这里的规则又微微不同,现在有一个N*M(N,M<=100)的方形矩形,在那么些矩形的每一个方格上都放有若干个樱桃,一条可爱的小蛇从矩形的
左上角初始起身,每一次运动都只可以移动一格,向右或向下,而每抵达一格饕餮的小蛇都会吗该职位上的樱桃吃个一干二净,直到抵达右下角时截止。而贪吃的小蛇不怕撑死,它只想吃到最多
的樱桃,请你告诉它他最多能吃到多少樱桃以及现实路径吧。(数据保证最优路线只有一条)

Input

每个输入包含多个测试用例,每个测试用例第一行给出N,M,接下去N行M列数据意味着每个岗位上的樱桃个数。(矩阵坐标从(1,1)先河)。

Output

对此每个测试用例输出第一行事能吃到的最大樱桃个数,接下去为小蛇所急需走的不二法门的坐标,每个坐标占一行。

Sample Input

4 4
1 2 3 7
3 4 2 1
1 5 4 8
10 3 0 3

Sample Output

28
(1,1)
(2,1)
(2,2)
(3,2)
(3,3)
(3,4)
(4,4)

Source

icpc7th@ahstu

    #include<iostream>
    #include<string>
    #include<fstream>
    #include<vector>
    #include<algorithm>
    using namespace std;
    typedef struct
    {
        int m_sum;
        vector<string> way;
    }MP;
    int mp[102][102];
    MP Mp[102][102];
    int N,M;
    string change(int a)
    {
        string A;
        while(a!=0)
        {
            A+=((a%10)+'0');
            a/=10;
        }
        reverse(A.begin(),A.end());
        return A;
    }
    void scan()
    {
        for(int i=0;i<=M;i++)
            mp[0][i]=0;
        for(int i=0;i<=N;i++)
            mp[i][0]=0;
        for(int i=1;i<=N;i++)
        {
            for(int j=1;j<=M;j++)
            cin>>mp[i][j];
        }
    }
    void hand_mp()
    {
        for(int i=1;i<=N;i++)
        {
            for(int j=1;j<=M;j++)
            {
                Mp[i][j].m_sum=mp[i][j]+((mp[i][j-1]>=mp[i-1][j])?mp[i][j-1]:mp[i-1][j]);
                mp[i][j]= Mp[i][j].m_sum;
                Mp[i][j].way=(mp[i][j-1]>=mp[i-1][j])?(Mp[i][j-1]).way:(Mp[i-1][j]).way;
                Mp[i][j].way.push_back(change(i));
                Mp[i][j].way.push_back(change(j));
            }
        }
    }
    void print()
    {
        cout<<Mp[N][M].m_sum<<endl;
        for(int i=0;i<Mp[N][M].way.size();i+=2)
        {
            cout<<"("<<Mp[N][M].way[i]<<","<<Mp[N][M].way[i+1]<<")"<<endl;
        }
    }
    int  main()
    {
       // freopen("贪吃蛇.in","r",stdin);
       // freopen("贪吃蛇.out","w",stdout);
        while(cin>>N>>M)
        {
            scan();
            hand_mp();
            print();
        }
        return 0;
    }

均分硬币


Time Limit:1000MS Memory Limit:65536K
Total Submit:14 Accepted:4

Description

有N堆硬币,编号分别为 1,2,…, N(N<=100)
每堆上有若干个硬币,可以在任一堆上取多少个硬币,然后移动。移动规则为:在数码为
1 堆上取的硬币,只好移到数码为 2 的堆上;
在号码为 N 的堆上取的硬币,只好移到数码为 N-1
的堆上;其他堆上取的硬币,可以移到邻近左边或左边的堆上。现在要求找出一种运动方法,用最少的活动次数使每堆上硬币
数都相同多。例如 N=4,4 硬币数分别为: ① 9 ② 8 ③ 17 ④ 6
移动3次可直达目标。

Input

各种输入包含两个测试用例,每个测试用例第一表现整数N硬币堆数,接下去一行N个数为相应堆上硬币的多寡。

Output

对于每个测试用例,输出其最少需要活动次数,若不可以均分则输出“Oh no!”

Sample Input

4
9 8 17 6

Sample Output

3

Source

icpc7th@ahstu

    #include<iostream>
    #include<fstream>
    using namespace std;
    int avg(int *A,int n)
    {
        int sum=0;
        int avge;
        int flag=0;
        for(int i=0;i<n;i++)
            sum+=A[i];
        avge=sum/n;
        if(avge*n==sum)
        {
            for(int i=0;i<n-1;i++)
            {
                if(A[i]!=avge)
                {
                    A[i+1]+=A[i]-avge;
                    flag++;
                }

            }
            cout<<flag<<endl;
        }
        else
            cout<<"Oh no!"<<endl;
    }
    int main()
    {
        int N;
        int A[101];
        while(cin>>N)
        {
            for(int i=0;i<N;i++)
                cin>>A[i];
            avg(A,N);
        }
        return 0;
    }

丢啊丢啊丢手绢


Time Limit:1000MS Memory Limit:65536K
Total Submit:17 Accepted:4

Description

在安科教室前的草地上围坐着N个同学1,2,3,…..N.(按顺序围成一个圈),然后从内部一个同学起头,拿着一手绢按编号从小到大的趋向一步一步绕着世界走,
一步经过一个同学,若干步后把手绢交给面前的校友,接到手绢的校友不改变方向用相同的形式把手绢交给另一个同桌后淘汰出游戏,凡是一个同桌离开圈子,剩下同学
把空缺消除再组成一个圆(相对地点不变)。现在报告你从头同学的编号和手帕n次行进的步数,你领会终剩下什么同学吗?

Input

各样输入包含三个测试用例,每个测试用例包括两片段:
率先有的两个数字num(参加游戏学生总数),i(初叶学生编号),n(手绢移动的次数)。
第二有些n个整数为n次手绢分别运动的步数。

Output

输出游戏停止后所剩学生的号子(按升序输出)。

Sample Input

6 2 3
2 3 4

Sample Output

5 6

Source

icpc7th@ahstu

    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<fstream>
    using namespace std;
    void init(vector<int> &A,int num)
    {
        for(int i=0;i<=num;i++){
            A.push_back(i);
        }
    }
    void game(vector<int> A,int *way,int n,int first)
    {
        int index;
         A.erase(A.begin()+first);
         index=first-1;
        for(int i=0;i<n;i++)
        {
            A.erase(A.begin()+(index+way[i])%A.size());
            index=(index+way[i])%A.size()-1;
        }
        for(int i=1;i<A.size();i++)
        cout<<A[i]<<" ";
        cout<<endl;
    }
    int main()
    {
        //freopen("¶ª°¡¶ª°¡¶ªÊÖ¾î.in","r",stdin);
        //freopen("¶ª°¡¶ª°¡¶ªÊÖ¾î.out","w",stdout);
        int num,first,n;
        vector<int> A;
        int way[100];
        while(cin>>num>>first>>n)
        {
            for(int i=0;i<n;i++)
                cin>>way[i];

            init(A,num);
             game(A,way,n,first);
             A.clear();
        }
        return 0;
    }

分糖果


Time Limit:1000MS Memory Limit:65536K
Total Submit:0 Accepted:0

Description

小洛,小欢,小涛是六个小屁孩,他们有一个联手的喜好—吃糖!小杨每日都会给他俩买糖吃,但他有个要求,每趟小杨会把买来的糖随机分成三堆,
(<=10^4)
几个小屁孩想要吃到糖,就务须按小杨的要求每便把自由一堆糖的一半放到任何糖堆里,最终使三堆糖的多寡和小杨所要求的完全一致,才被允许吃.
(若一堆糖为奇数个,它的一半为较少的这有些)。那么他们至少需要活动多少次才能吃到糖果。

Input

各类输入包含四个测试用例,每个测试用例第一行提交3个数字为起首的糖堆数量,第二行3个数字为小杨要求糖堆最终数额。

Output

对此每个测试用例输出一行为其最少移动次数,若不容许达到要求输出“Unfind”。

Sample Input

6 10 3
6 5 8

1 2 5
3 0 5

Sample Output

1
Unfind

Source

icpc7th@ahstu

    #include<iostream>
    #include<queue>
    #include<string>
    #include<map>
    #include<cstdio>
    #include<sstream>
    using namespace std;

    typedef struct
    {
        int step;
        int candy[3];
    } ST;
    map<string,int>mp;
    int init[3];
    int target[3];
    void state(ST &S,int i)
    {
        int f,s,t;
        f=S.candy[0];
        s=S.candy[1];
        t=S.candy[2];
        S.step++;
        switch(i)
        {
        case 1:
            S.candy[0]=f-f/2;
            S.candy[1]=s+f/2;
            break;
        case 2:
            S.candy[0]=f+s/2;
            S.candy[1]=s-s/2;
            break;
        case 3:
            S.candy[0]=f-f/2;
            S.candy[2]=t+f/2;
            break;
        case 4:
            S.candy[0]=f+t/2;
            S.candy[2]=t-t/2;
            break;
        case 5:
            S.candy[1]=s-s/2;
            S.candy[2]=t+s/2;
            break;
        case 6:
            S.candy[1]=s+t/2;
            S.candy[2]=t-t/2;
            break;
        }
    }
    int Search(int *init,int *target,queue<ST> &Q,int &STEP)
    {
        ST flag;
        string fl,l;
        flag.step=0;
        flag.candy[0]=init[0];
        flag.candy[1]=init[1];
        flag.candy[2]=init[2];
        Q.push(flag);
        for(int i=0; i<3; i++)
        {
            char b[15];
            sprintf(b,"%d",flag.candy[i]);
            fl+=b;
        }
        mp[fl]=1;
        if(flag.candy[0]==target[0]&&flag.candy[1]==target[1]&&flag.candy[2]==target[2])
        {
            STEP=flag.step;
            return 1;
        }
        while(!Q.empty())
        {
            flag=Q.front();
            for(int i=1; i<=6; i++)
            {
                state(flag,i);
                if(flag.candy[0]==target[0]&&flag.candy[1]==target[1]&&flag.candy[2]==target[2])
                {
                    STEP=flag.step;
                    return 1;
                }
                fl="";
                for(int i=0; i<3; i++)
                {
                    char b[15];
                    sprintf(b,"%d",flag.candy[i]);
                    fl+=b;
                }
                if(mp[fl]!=1)
                {
                    Q.push(flag);
                    mp[fl]=1;
                }
                flag=Q.front();
            }
            Q.pop();
        }
        return 0;
    }
    int main()
    {
        int f,s,t;
        int F,S,T;
        int STEP;
       // freopen("分糖果.in","r",stdin);
        //freopen("分糖果.out","w",stdout);
        while(cin>>f>>s>>t>>F>>S>>T)
        {
            if((f+s+t)!=(F+S+T))
            {
                cout<<"Unfind"<<endl;
                continue;
            }
            queue<ST> Q;
            init[0]=f;
            init[1]=s;
            init[2]=t;
            target[0]=F;
            target[1]=S;
            target[2]=T;
            if(Search(init,target,Q,STEP))
                cout<<STEP<<endl;
            else
                cout<<"Unfind"<<endl;
            mp.clear();
        }
        return 0;
    }

埋炸弹啦~


Time Limit:1000MS Memory Limit:65536K
Total Submit:47 Accepted:18

Description

小明是个埋弹专家同时也是个数学爱好者,他老是进行埋弹任务时都喜爱数字操纵埋在哪个地方,他会选出六个数字然后分别把它们转化成八位二进制数,第一个作为横向坐标(从左往右),
第二个作为纵向(从上往下)坐标构成一个8*8的矩阵,而他埋弹的地方当然就是反正坐标中1的交叉点。请把他埋的职务表示出来,炸弹地点用‘+’表示,其他地点用‘-’表示。

Input

每个输入包含两个测试用例,每个测试用例一行为两个整数
a,b(0<=a,b<256)为小明所选定的五个数。

Output

对于每个测试用例,输出一个8*8的矩阵,按要求注脚炸弹地方。

Sample Input

9 18

Sample Output

--------
--------
--------
----+--+
--------
--------
----+--+
--------

Source

icpc7th@ahstu

    #include<iostream>
    #include<string>
    #include<fstream>
    #include<algorithm>
    using namespace std;
    string X,Y;
    int x,y;
    void init()
    {
        while(x!=0)
        {
            X+=((x%2)+'0');
            x/=2;
        }
        while(y!=0)
        {
            Y+=((y%2)+'0');
            y/=2;
        }
        reverse(X.begin(),X.end());
        reverse(Y.begin(),Y.end());
        int l1=X.size();
        int l2=Y.size();
        for(int i=0;i<8-l1;i++)
            X.insert(X.begin(),'0');
        for(int i=0;i<8-l2;i++)
            Y.insert(Y.begin(),'0');
    }
    void bomb()
    {
        for(int i=0;i<Y.size();i++)
        {
            for(int j=0;j<X.size();j++)
        {
            if(Y[i]=='1'&&X[j]=='1')
                cout<<'+';
            else
                cout<<'-';
        }
        cout<<endl;
        }
    }
    int main()
    {
        //freopen("ÂñÕ¨µ¯À²~.in","r",stdin);
       // freopen("ÂñÕ¨µ¯À²~.out","w",stdout);
        while(cin>>x>>y)
        {
            init();
            bomb();
            X="";
            Y="";
        }
        return 0;
    }

化学老师的处置


Time Limit:1000MS Memory Limit:65536K
Total Submit:0 Accepted:0

Description

小明的化学战绩很差,他的园丁对她恨铁不成钢啊,于是想了一个办法——把他关在了一个密室里,出不来不给吃饭。那多少个把小明急坏了。。
小明发现密室的墙上写了无数化学方程式中。化学方程式,也称之为化学反应方程式,是用化学式表示物质化学反应的姿势。化学方程式反映的是客观事实。因而书写化学方程式要服从五个尺码:一是必须以客观事实为底蕴;二是要听从质量守恒定律。
化学方程式不仅标志了反应物、生成物和影响条件。同时,化学计量数代表了各反应物、生成物物质的量关系,通过相对分子质地或相对原子质量还是可以够表示各物质之间的质料关系,即各物质之间的质料比。对于气体反应物、生成物,还足以平昔通过化学计量数得出体积比。例如:2NaOH+H2SO4=Na2SO4+2H2O
经过多次试探、推理,小明发现密码是4位数字,就暗藏在化学方程式等号后的率先个成员中,其分子量就可能是密码(若分子量不足4位,前边加0)。

好在小明还记得墙上各化学方程式用到的化学元素的原子量如下:

N | C | O | Cl | S | H | Al | Ca | Zn | Na | B | Ni

14 | 12 | 16 | 35 | 32 | 2 | 27 | 40 | 65 | 23 | 11 | 59

你能帮小明尽快找到密码吗?

Input

输入包含多组测试用例。
各样测试用例 第一行: K,表示有K个化学方程式;
接下去有K行,每行为一个化学方程式

Output

对于每个化学方程式输出一行:即密码。

Sample Input

2
2C+O2=2CO
Ca2CO3+H2O=Ca2(OH)2+CO2

Sample Output

0056
0116

Source

icpc7th@ahstu

    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<iterator>
    #include<vector>
    #include<map>
    #include<cstdlib>
    #include<cstdio>
    #include<fstream>
    using namespace std;
    map<string,int>mp;
    vector<string>sp;
    vector<string>sp_num;
    string total;
    void init()
    {
        mp["Na"]=23;mp["Zn"]=65;
        mp["Ca"]=40;mp["Al"]=27;
        mp["H"]=2;  mp["S"]=32;
        mp["Cl"]=35;mp["O"]=16;
        mp["C"]=12; mp["N"]=14;
         mp["B"]=11; mp["Ni"]=59;
    }
    int calculate(string B)
    {
        int sum=0;
        for(int i=0; i<B.size(); i++)
        {
            string flag;
            flag+=B[i];
            flag+=B[i+1];
            if(mp[flag]!=0)
            {
                int f=i+2;
                string n;
                while(isdigit(B[f]))
                {
                    n+=B[f];
                    f++;
                }
                if(n=="")
                    n="1";
                i=(--f);
                sum+=mp[flag]*atoi(n.c_str());
            }
            else
            {
                int l=i+1;
                string n;
                while(isdigit(B[l]))
                {
                    n+=B[l];
                    l++;
                }
                if(n=="")
                    n="1";
                string K;
                K+=B[i];
                sum+=mp[K]*atoi(n.c_str());
                i=(--l);
            }
        }
        return sum;
    }
    int T_calculate()
    {
        int S=0;
        for(int i=0; i<sp.size(); i++)
        {
            S+=calculate(sp[i])*(atoi(sp_num[i].c_str()));
        }
        return S*atoi(total.c_str());
    }
    void Find(string A)
    {
        string B;
        string::iterator it;
        for(it=(find(A.begin(),A.end(),'=')+1); it!=A.end(); it++)
        {
            if(*it=='+')
                break;
            B+=(*it);
        }
        while(isdigit(B[0]))
        {
            total+=B[0];
            B.erase(B.begin());
        }
        if(total=="")
            total="1";
        string flag;
        int o=3;
        while(!B.empty())
        {
            if(o==0)
                while(1);
            o--;
            if(B[0]=='(')
            {
                string::iterator it,it1;
                string F;
                it=find(B.begin(),B.end(),')');
                F.assign(B.begin()+1,it);
                sp.push_back(F);
                F="";
                it1=(++it);
                while(isdigit((*it))&&it!=B.end())
                {
                    F+=*it;
                    it++;
                }
                if(F=="")
                    sp_num.push_back("1");
                else
                    sp_num.push_back(F);
                B.erase(B.begin(),(it));
            }
            else
            {
                string flag;
                string::iterator it=(find(B.begin(),B.end(),'('));
                flag.assign(B.begin(),(it));
                sp.push_back(flag);
                B.erase(B.begin(),(it));
                sp_num.push_back("1");
            }
        }
    }
    int main()
    {
        //freopen("化学老师的惩罚.in","r",stdin);
        //freopen("化学老师的惩罚.out","w",stdout);
        int N;
        init();
        while(cin>>N)
        {
        while(N--)
        {
            string A;
            cin>>A;
            Find(A);
            printf("%04d\n",T_calculate());
            sp.clear();
            sp_num.clear();
            total="";
        }
        }
        return 0;
    }

水题!


Time Limit:1000MS Memory Limit:65536K
Total Submit:116 Accepted:44

Description

杯子高H,水高h,杯顶半径R,杯底半径r,求水的体积。(Pi=3.1415926)

Input

H R r h

Output

水的体积

Sample Input

10 8 7 4

Sample Output

855.56

Hint

圆台计算公式V=1/3*Pi*h*(R^2+r^2+R*r)

Source

icpcth7@ahstu

admin

网站地图xml地图