1. 程式人生 > >2016廣東工業大學新生杯決賽網路同步賽暨全國新生邀請賽總結

2016廣東工業大學新生杯決賽網路同步賽暨全國新生邀請賽總結

比賽連結:點這裡

題目:

Problem A: pigofzhou的巧克力棒

Description

眾所周知,pigofzhou有許多妹子。有一天,pigofzhou得到了一根巧克力棒,他想把這根巧克力棒分給他的妹子們。具體地,這根巧克力棒長為 n,他想將這根巧克力棒折成 n 段長為 1 的巧克力棒,然後分給妹子們。 但是他妹子之一中的 15zhazhahe 有強迫症。若它每次將一根長為 k 的巧克力棒折成兩段長為 a 和 b 的巧克力棒,此時若 a=b,則15zhazhahe會得到一點高興值。 pigofzhou想知道15zhazhahe最多能獲得多少高興值。

Input


輸入資料為T組(T <= 10000),每組資料讀入一個n(n<=1000000000)

Output

一行一個整數代表能獲得的最大高興值

Sample Input

15

Sample Output

3 程式碼:

思路:好吧,我承認這道題我做的複雜了。。時間複雜圖太高,這道題和下一道題一模一樣,甚至程式碼都不用改,但是我的這個程式碼交到B題會超時,規律是2的n次方的時候,是2的n次方減1

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int cifang(int n)//計算2的n次方
{
    int sum=1;
    while(n--)
    {
        sum*=2;
    }
    return sum;
}
int a[35];
int main()
{
    int q=1;
    for(int i=1; i<=30; i++)
    {
        a[q++]=cifang(i);
    }//打一張表,2的0次方到2的30次方
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        int sum=0;
        while(n>0)
        {
            if(n==1)
            {
                break;
            }
            for(int i=1; i<=30; i++)//迴圈2的次方數
            {
                if(n==a[i])//如果n恰好等於2的某一個次方
                {
                    sum+=a[i]-1;//次數正好加上它-1
                    n-=a[i];//更新n的值
                    break;
                }
                if(n<a[i]&&n>a[i-1])//在2的n-1次方與2的n次方之間
                {
                    sum+=a[i-1]-1;
                    n-=a[i-1];
                }
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}

Problem B: Zhazhahe究竟有多二

Description

Zhazhahe竟然能二到把耳機扔到洗衣機裡去洗,真的是二到了一種程度,現在我們需要判斷一下zhazhahe二的程度(就是計算zhazhahe的腦殘值有幾個2的因子),下面給你一個nn!表示zhazhahe的腦殘值。

Input

輸入一個正整數t(0<t<3000)表示樣例組數,每組樣例輸入一個正整數n(0<n<1e18)n!表示zhazhahe的腦殘值

Output

輸出一個正整數表示zhazhahe二的程度

Sample Input

32415

Sample Output

1311

HINT

思路:

仔細讀題,會發現這道題和第一道題有什麼區別,完全沒有嘛。。,但是你用下面的程式碼交一下A題,然後就神奇的過了,

其實兩道題的規律都是2的n次方的時候是2的n次方減1

#include<stdio.h>
int main()
{
    long long int t;
    scanf("%lld",&t);
    while(t--)
    {
        long long int n,s=0;
        scanf("%lld",&n);
        while(n)
        {
            s+=n/2;
            n/=2;
        }
        printf("%lld\n",s);
    }
}

Problem C: 剁手女生節

Description

由於女生節準備到了,ming打算給班上女生送一份大禮。沒錯,就是數學練習冊!
ming先前就已經收藏了 n 本練習冊了,一直不捨得做,這次突然決定把它們都拿出來當作禮物送出去!
但是,ming班上一共有 4 個女生,為了不要顯得自己偏愛哪一個,他覺得每個女生都應該分到同等數量的練習冊。
這樣的話,原來的 n 本就可能不太夠了。於是他去逛亞馬當商城。
他發現,最近ACM(Association of Counting Method)又出版了好多新版數學練習冊:高數、線代、離散、概率論…
而且商店有三種促銷優惠套餐:
第一種:任選 1 本練習冊,送歐幾里德主題套尺。只需 a 個比特幣;
第二種:任選 2 本練習冊,送萊布尼茲同款2B鉛筆。只需 b 個比特幣;
第三種:任選 3 本練習冊,送愛因思坦專用橡皮擦。只需 c 個比特幣。
那麼問題來了:吃土ming如何用最少的比特幣購買若干本練習冊,使得全部(包括原來的n本)可以平分給四個女生?

Input

每組輸入是一行四個整數:n,a,b,c(1 <= n,a,b,c <= 1e9)意思如題目描述。

Output

對每組輸入,輸出一行一個整數,表示ming要花的最少的比特幣數。

Sample Input

31 1 3 46 2 1 14 4 4 4

Sample Output

310
思路:這道題一共三種情況,水過

程式碼:

#include<stdio.h>
#include <algorithm>
#define ll long long int
using namespace std;
int main()
{
    ll t;
    scanf("%lld",&t);
    while(t--)
    {
        ll n,a,b,c;
        scanf("%lld%lld%lld%lld",&n,&a,&b,&c);
        if(n%4==0)
            printf("0\n");
        else
        {
            ll x=(4-(n%4));
            if(x==1)printf("%lld\n",min(min(a,c*3),c+b));
            if(x==2)printf("%lld\n",min(min(2*a,b),c*2));
            if(x==3)printf("%lld\n",min(min(3*a,a+b),c));
        }
    }
    return 0;
}

Problem D: 勤奮的漣漪2

Description

漣漪進入集訓隊後,他會去實驗室訓練或者去操場鍛鍊。 接下來n天,每天的情況是一下4種中的一種: 1.當天體育館關門了和沒有訓練賽 2.當天體育館關門了和有訓練賽 3.當天體育館開放和沒有訓練賽 4.當天體育館開放和有訓練賽 漣漪知道之後n天的情況。 漣漪每一天可以休息,或者打訓練賽(當天有訓練賽)或者運動(當天體育館開放)。 漣漪要制定一個訓練計劃,決定每天干什麼,但是漣漪不會連續兩天都運動或者連續兩天都打訓練賽, 請幫漣漪找出她最少休息的天數(她不打訓練賽和運動)。 休息的時候,她會做下面的數學題

Input

第一行一個整數t(t<=100),代表測試資料, 第二行一個整數 n(1<=n<=100) 第三行有n個數a1,a2,a3,....an(0<=ai<=3)) ai=0 ,代表第一種情況 ai=1,代表第二種情況 ai=2 ,代表第三種情況 ai=3 ,代表第四種情況

Output

輸出 一個數 表示(漣漪休息的天數) 乘以(數學題的答案的積)。

Sample Input

471 3 3 2 1 2 3111213

Sample Output

0000 思路:看註釋

程式碼:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int a[110];
int n;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {

        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        int sum=0;
        for(int i=0; i<n; i++)
        {
            if(a[i]==3)//體育館和訓練賽都能參加
            {
                if(a[i-1]!=3)//如果上一天的狀態不是都開門
                    a[i]=3-a[i-1];//轉換狀態
            }
            else
            {
               if(a[i]==a[i-1])
                {
                      a[i]=0;//狀態已經轉換了,這一項和前一項相等時就標記為0
                }

            }
        }
        for(int i=0; i<n; i++)
        {
            if(a[i]==0)
                sum++;
        }
        printf("%d\n",sum*(-24));

    }
    return 0;
}
/* **********************************
     體育館     訓練賽            ***
 0     0          0               ***
 1     0          1               ***
 2     1          0               ***
 3     1          1               ***
** *********************************/

Problem E: 窮遊中國在統題

Description

Travel_poorly隊是廣工大目前最年輕的金牌隊伍,隊內成員分別是tmk、YFQ、Maple。這天他們接到教練的order要給新生杯統題,統題是個不輕鬆的工作,要評估各個題目的難度,設計出一套有梯度的套題,使得做題的情況有區分度。tmk很快想出瞭解決的辦法,他給每道題目都設定了一個難度值,然後按照難度值進行篩選題目,這時候他發現難度值剛開始有可能是無序的,於是他決定要讓全部題目都按照難度值從小到大排好序。 這時候YFQ說讓他來排序,排序是一個展現演算法魅力的過程,他要通過一種有趣的方法來給題目的難度值排序: 首先他把題目劃分成很多組,每組的題目都是連續的,例如某一組包含從i到j的題目,那麼這一組包含的是第i,i+1,i+2,i+3,...,j題。 這樣每道題都屬於某一個組,然後他再到組內把題目按照難度值進行從小到大排序。 當每個組內都進行排序之後,最終全部題目的難度值將按照從小到大的順序排列好。 我們知道每一組裡面的題目越多,排序的壓力就越大,所以Maple提出一個合理的要求,就是讓每個組裡面的題目數量儘可能的少,聰明的ACMer,你知道Travel_poorly一共要分出多少個組嗎?

Input

第一行是一個整數t ( t<= 10 ),表示有t組資料。在每組資料中: 第一行是一個整數n ( n<=1000 00 ),表示題目的總數; 第二行是n個整數A1,A2,A3...An ( 0<=Ai<= 1000 000 000),表示每道題目的難度值

Output

對於每組資料,輸出一個正整數,表示一共要分出多少個組能滿足Travel_poorly的要求,每兩組樣例之間輸出一個空行。

Sample Input

253 2 5 4 655 4 3 2 1

Sample Output

31 思路:好吧。。。我不會抓狂

Problem H: 《為什麼會變成這樣呢》

Description

“第一次有了喜歡的人,還得到了一生的摯友,兩份喜悅互相重疊,這雙重的喜悅又帶來了更多更多的喜悅,本應已經得到了夢幻一般的幸福時光,然而,為什麼,會變成這樣呢?”雙重的喜悅感卻無法帶來更多的幸福,現在,雪菜在很多喜悅感之中只想要得到兩份不重疊的喜悅感(其他的喜悅感都是重疊的),你能幫她找出這兩份不同的喜悅感是多少嗎?

Input

第一行一個整數T,代表資料的組數(1<=T<=10),接下來T組資料,每組資料的第一行是一個整數n(1<=n<=1000000),第二行是n個整數ai(0 <= ai <= 1000000000)代表喜悅感,每兩個整數之間有一個空格,題目保證有且僅有兩個不同的整數出現一次,其他的整數都是出現兩次。

Output

對於每組資料,輸出兩個整數,分別代表兩份不同的喜悅感,中間有一個空格,並且喜悅感較小的先輸出。

Sample Input

262 2 1 1 3 441 1 3 4

Sample Output

3 43 4

思路:註釋就不寫了把,應該都能看懂,用了佇列,還好這個題只有兩個不一樣的。。

程式碼:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        queue<int>s;
        int n;
        int k;
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {

            scanf("%d",&k);
            if(!s.empty())
            {
                if(k==s.front())
                    s.pop();
                else
                    s.push(k);
            }
            else
            {
                s.push(k);
            }
        }
        int a=s.front();
        s.pop();
        int b=s.front();
        s.pop();
        printf("%d %d\n",min(a,b),max(a,b));
    }
    return 0;
}
ps:至於F(輸出ac),G(求組合數)有點水,就不在這貼上來了,J題直接打表,I題麼。。這個不會做,它的後臺資料有問題,隨便交個程式碼都能過,也不能判斷程式碼的正確性,就不弄了