2016 "Bird Cup" ICPC7th@ahstu--“波導杯”安徽科技學院第七屆程序設計大賽

“波導杯”安徽科技學院第七屆程序設計大賽

原文章網頁


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)主辦的一項旨在展示大學生創新能力、團隊精神和在壓力下編寫程序、分析和解決問題能力的著名競賽。2010年以來,我校參與了歷屆安徽省 ACM 程序設計競賽,並取得了優異的成績。爲選拔校 ACM 參賽隊員,將舉辦波導杯” 安徽科技學院第七屆計算機程序設計大賽,熱忱歡迎廣大程序設計愛好者踊躍參加。

主辦方:安徽科技學院教務處、信息與網絡工程學院

承辦方:信息與網絡工程學院

贊助方:寧波波導軟件有限公司(獨家贊助)

一、 比賽時間:2016  4 23(週六)上午 8:0012:00

二、比賽地點:計算機與網絡實驗中心(力行樓六樓)

三、比賽設獎:設一等獎8%、二等獎12%、三等獎15%

六、競賽相關:

競賽語言:C/C++/JAVA 環境:DevCpp /CodeBlock /Eclipse

比賽試題:採用 ICPC 樣式——賽題 810

注意事項:

·  1. 練習比賽網站(安科 OJ):http://183.167.205.82:8081/JudgeOnline/

·  2. 計算機系 ACM/ICPC 學生活動室位於力行樓六樓,歡迎交流。

比賽 QQ 羣:173592864(波導杯第七屆校ACM賽)


Problem IdTitle
1366 Problem ADotaer vs Loler
1367 Problem Bso 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章