第三屆H-star 程式設計競賽初賽題解

來源:互聯網
上載者:User

標籤:

     1.剪紙片:這是一道簡單的題目,假如你身邊有一張紙,一把剪刀,在H-star的比賽現場,你會這麼做:(1). 將這張紙剪成兩片(平行於短邊剪開);(2)將其中一片剪成一個圓,作為圓柱的底面;(3) 紙的另一片的一邊沿著圓的周長將圓圍起來,直到圍成一圈,形成一個無蓋的圓柱體。需要注意的是,紙片可能會有重疊部分。聰明的你機智的你喜歡思考的你這時候就開始想,一張紙片按上述方式所組成的圓柱的最大體積是多少呢?請你用編程解決這個問題。

輸入

輸入第一行包含一個數字t代表接下來有t組資料;
接下來的t行,輸入兩個數字w, h(1 ≤ w ≤ h ≤ 100),分別代表紙片的寬和高。

輸出

對每一組資料輸出紙片所能構成的最大圓柱體的體積v(保留小數點的後三位小數)。

範例輸入
310 10 10 50 10 30
範例輸出
54.247785.398412.095
提示

第一個測試範例,圓的半徑是1.591549, 第二個測試範例,圓的半徑是5, 第三個測試範例,圓的半徑是3.621795.PI用acos(-1)表示。

思路:假定地面半徑是r,那麼r必定小於等於w的1/2,這時候以w為高,那麼必須滿足h-2*r >= 2*pi*r,求的最大值,還有一種情況是以h-2*r為高,那麼必須滿足,w>=2*pi*r通過求導解得最大值,最後結果在兩個最大值之間取最大值!

代碼:

#include <iostream>#include <cstdio>#include <cmath>  using namespace std;const double pi = acos(-1); double l,h;int t; int main(){    cin >> t;    while(t--){        cin >> h >> l;        double r = min(h/2.0,l/(2.0+2.0*pi));        double v = pi*r*r*h;        r = min(l/3.0,h/(2.0*pi));        v = max(v,pi*r*r*(l-2*r));        printf("%.3f\n",v);    }    return 0;}

2.廢品收集記:敲代碼不是唯一的出路,但是假如H-star題目太難了,讓你放棄了以後當程式員的念頭,放棄身邊的那個Ta,那麼你就有可能去撿破爛,假如你去撿破爛,就會碰到下述問題:
在河海有n個垃圾桶,每個垃圾桶裡面都有價值為m,體積為b的廢品。但是你的背包體積只有V,為了賺更多錢,為了身邊的Ta更幸福,你每一次撿破爛,都希望自己體積為V的背包裡裝的廢品價值盡量多。
所以你又想起你曾經敲過的代碼,你決定寫一個程式解決這個問題。

輸入

輸入一個數字t,表示有t組資料:
每一組資料有三行:
第一行:輸入兩個數字n,V(n <= 1000, V <= 1000);n表示垃圾桶的數量,V表示背包的容量
第二行:輸入包括n個數字,代表每個垃圾桶中廢品的價值m
第三行:輸入包括n個數字,代表每個垃圾桶中廢品需要佔用的背包的容量b

輸出

輸出你每次出去撿破爛背包所能裝下破爛的最大價值(保證每次輸出資料都在整形範圍內)。

範例輸入

1

5 10

1 2 3 4 5

5 4 3 2 1

範例輸出

  14

 思路:簡單的單重背包裸體,就是遞推關係,建議看一下背包九講裡面的東西就可以了

代碼:

#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring> using namespace std;int n,t,bag;int v[1005];int vl[1006];int dp[1005]; int main(){    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&bag);        for(int i= 0; i < n; i++)        {            scanf("%d",&vl[i]);        }        for(int i= 0; i < n; i++)        {            scanf("%d",&v[i]);        }        memset(dp,0,sizeof(dp));        for(int i = 0;i < n;i++){            for(int j = bag;j > 0;j--){                if(j >= v[i]){                    dp[j] = max(dp[j],dp[j-v[i]]+vl[i]);                }            }        }        printf("%d\n",dp[bag]);    }    return 0;}

3.

3.Northcott遊戲:alpha和GrayGraySmall正在玩一種Northcott遊戲,可是alpha老是輸,因此他懷疑這個遊戲是不是有某種必勝策略,鬱悶的alpha現在向你求救了,你能幫幫他嗎?
遊戲規則是這樣的:
,遊戲在一個n行m列(1 ≤ n ≤ 1000且2 ≤ m ≤ 100)的棋盤上進行,每行有一個黑子(黑方)和一個白子(白方)。執黑的一方先行,每次玩家可以移動己方的任何一枚棋子到同一行的任何一個空格上,當然 這過程中不許越過該行的敵方棋子。雙方輪流移動,直到某一方無法行動為止,移動最後一步的玩家獲勝。alpha總是先下(黑方)。圖1是某個初始局面,圖二是 alpha移動一個棋子後的局面(第一行的黑子左移兩步)。

輸入

 輸入資料有多組。每組資料第一行為兩個整數n和m,由空格分開。接下來有n行,每行兩個數Ti,Ji (1 ≤ Ti, Ji ≤ m)分別表示alpha和GrayGraySmall在該行棋子所處的列數。
注意:各組測試資料之間有不定數量的空行。你必須處理到檔案末。

輸出

  對於每組測試資料輸出一行你的結果。如果當前局面下alpha有必勝策略則輸出“I WIN!”,否則輸出“BAD LUCK!”。

範例輸入

3 6

4 5

1 2

1 2

範例輸出

BAD LUCK!

 思路:這個是博弈論的簡單題目,沒啥要說的,反正比賽不會,原題是杭電的題,

代碼:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath> using namespace std; int n,m;int a,b; int main(){    while(~scanf("%d%d",&n,&m)){        int tag = 0;        while(n--){            scanf("%d%d",&a,&b);            tag ^= abs(a - b) - 1;        }        if(tag){            printf("I WIN!\n");        }        else{            printf("BAD LUCK!\n");        }    }    return 0;}

4.我在NE304敲代碼的時候吃女神送給我的糖果一個立志做程式員的人,做什麼都會想到敲代碼。小明的女神曾經送給他一堆糖果,但是他一直捨不得吃,最後等到了H-Star比賽,小明就把女神送給他的蘋果帶到了比賽現場,當作女神對他的祝福。但是問題往往就在這時候浮現在他的腦海:小明有一個癖好,吃糖果的時候,不喜歡連著吃同一種糖果,喜歡先吃一種,下一次吃另一種(小明一次只吃一顆糖果);可是小明不知道是否存在一種吃糖果的順序使得他能把所有糖果都吃完。小明認為這是女神對他的一個考驗,也是祝福,所以馬上在NE304敲起了代碼…

輸入

 第一行有一個整數T,接下來T組資料,每組資料佔2行,第一行是一個整數N(0<N<=1000000),第二行是N個數,表示N種糖果的數目Mi(0<Mi<=1000000)。

輸出

對於每組資料,輸出一行,包含一個"Yes"或者"No"。

範例輸入

2

3

4 1 1

5

5 4 3 2 1

範例輸出

No

Yes

思路:很簡單的題目了,對於一種的n個糖果必須有其他種類的糖果的總和>=n-1來分開,這樣就沒有什麼難度了,坑點就是總和會超過int。

代碼:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm> using namespace std; long long  a[1000005];int n; int main(){    int t;    cin >> t;    while(t--)    {        cin >> n;        long long sum = 0;        for(int i = 0; i < n; i++)        {            cin >> a[i];            sum += a[i];        }        int tag = 0;        for(int i = 0; i < n; i++)        {            if(a[i] > sum-a[i]+1)            {                tag  =1;                break;            }        }        if(!tag)        {            cout << "Yes" << endl;        }        else        {            cout << "No" << endl;        }    }    return 0;}

 

5.Lecture:coco有一個說話特別特別快的新圖論老師,因為說話太快所以coco雖然勉強能跟得上老師的課但是卻沒辦法記好筆記,好在coco很聰明,她想到了一個方法讓自己跟得上課並記筆記。
coco知道兩種語言,而老師上課的時候總是用第一種語言,語言中的單詞都是由英文小寫字母組成,每一門語言又由幾個單片語成。對每一門語言來說,所有的 單詞都是相互獨立的,只是拼字不同。而且,對於這些語言來說每個單詞都是一一對應的,對於一門語言的一個單詞來說,它都會在另一門語言中有確切的單詞和確切的意思.。
coco可以卸下老師講的每一個單詞,不管是第一種語言還是第二種語言。當然,在上課期間coco寫下的每一個單詞都是這兩種語言中最短的那個。如果單詞長度一樣,coco會傾向於寫第一種語言。
現在給你一段老師講課的文本,找出這節課coco會在筆記本上記錄的內容。

輸入

第一行包含兩個整數,n 和 m( 1<= n,m <= 3000),  老師堂內容的單詞數和這些語言中的單詞數。
接下來的 m 行包含了這些單詞.第 i 行包含兩個串 ai, bi。ai 是第一門語言的單詞, bi 是第二門語言的單詞,這兩個單詞擁有相同的意思.輸入保證沒有相同的單詞出現在兩種語言中,而且每個單詞在一中語言中只出現一次.
接下來的一行有 n 個空格隔開的串 c1,c2,...,cn---講課的內容.保證每一個 Ci 串都會在集合{a1,a2,...am}中.
所有的串在輸入中都不空,每一個單詞都由不超過10個英文小寫字母組成.

輸出

輸出有 n 個單詞::你將會記錄在筆記本中的講課內容。單詞順序不變。

範例輸入

4 3

codeforces codesecrof

contest round

letter message

codeforces contest letter contest

範例輸出

codeforces round letter round

思路:這道題不難,直接類比暴力就可以過了。

代碼:

#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring> using namespace std; int n,m; struct point{    char a[15];    char b[16];} p[1005];char c[15]; int main(){    cin >> n >> m;    for(int i = 0; i < m; i++)    {        cin >> p[i].a >> p[i].b;    }    while(n--)    {        cin >> c;        for(int i= 0; i <m; i++)        {            if(strcmp(c,p[i].a) == 0 || strcmp(c,p[i].b) == 0)            {                if(strlen(p[i].a) > strlen(p[i].b))                {                    cout << p[i].b;                }                else                {                    cout << p[i].a;                }                if(n != 0){                   cout << " ";                }            }        }    }    return 0;}

 

6.迴文數:迴文數是順著讀和反著讀都一樣的數字,給你一個數字,請你判斷它是不是迴文數。

輸入

輸入一個整數t(t在int範圍內)

輸出

如果這個數是迴文數,則輸出Yes,如果不是迴文數,則輸出No

範例輸入

121

範例輸出

Yes

提示

 思路:前道題嘛,那又要說的呢,最好用字串表示吧,主辦方資料太弱,int好像能過

代碼:

#include <iostream>#include <cstdio>#include <cstring> using namespace std; int n;char a[15]; int main(){    scanf("%s",a);    int tag = 0;    int len = strlen(a);    for(int i= 0; i <= len/2;i++){          if(a[i] != a[len-i-1]){            tag = 1;            break;          }    }    if(tag){        printf("No\n");    }else{        printf("Yes\n");    }    return 0;}

後面的題,咿咿呀呀的就不會做了呢,

第三屆H-star 程式設計競賽初賽題解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.