四章(C++)

鏈接:https://ac.nowcoder.com/acm/contest/6012/A
來源:牛客網

題目描述

本題輸入量較大,請儘量不要使用cin等較慢的輸入方式

有一天先輩邀請後輩到家裏吃麪包喝紅茶,先輩家裏有 n 個大小爲 1 的麪包和 m 個大小爲 2 的麪包,先輩要求後輩把所有面包喫完。

後輩每喫一塊麪包,就會積累等同麪包大小的飽腹值,當後輩的飽腹值 > k 時,就會因爲喫太撐沒力氣昏倒。後輩可以選擇喝一次紅茶消除當前所有的飽腹值,但是紅茶被先輩下了藥,所以後輩想在不昏倒的情況下,喝紅茶的次數儘可能少。

輸入描述:

本題有多組數據,輸入文件第一行有一個正整數 T 表示數據組數。
對於每一組數據,有三個數 n, m, k ,表示先輩家大小爲 1 的麪包數量和大小爲 2 的麪包數量,以及飽腹值的上限 k 。

輸出描述:

對於每一組數據輸出一個數並換行,表示後輩最少喝的紅茶數量。

示例1

輸入

1
14 5 14

輸出

1

備註:

1≤T≤10^6
1≤n,m≤10^18
2≤k≤10^18




這個題目給了我十分深刻的印象,事實告訴我們:

數據大一定要開long long

我的總體思路是分類討論(這個方法不太好)。
將k進行討論,若k爲偶數爲一種,若k爲奇數也爲一種。
當k爲奇數時,若m/k*2>=n分一種,else分另一種。
偶數思想:首先得先將大小爲2的麪包喫完,有時會有殘羹剩飯,於是把大小爲2的轉化爲大小爲1的,接着再將大小爲一的喫完。
奇數思想:如果k爲奇數,那麼定然要有一個大小爲1的來補位,但是若大小爲1的不夠怎麼辦呢?此時就要分類討論。
1、m/k*2>=n
這表示大小爲1的足夠,此時只需要處理餘下的就行了。
2、m/k*2<n
這表示大小爲1的不夠,缺少的怎麼辦呢?
答:不用管!
有人又問:爲啥不用管?
答:將k-1轉化成偶數就行了。
於是,我們就將這種情況轉化爲了k爲偶數那種情況。
知道思路,代碼就好寫了:

#include<bits/stdc++.h>
using namespace std;
int T;
int n,m,k;
int work(int x,int y,int z) {
    int ans=0;
    int sum=0;
    if(z%2==0)
    {
        sum=sum+y*2+x;
        if(sum%z==0)ans--;
        ans=ans+sum/z;
        return ans;
    }
    else
    {
        if(y/z*2>=x)
        {
            ans=ans+x;
            z--;
            z/=2;
            ans=ans+(y-x)/z;
            ans--;
        }
        else
        {
            ans=ans+(y)/(z/2);
            x=x-(y)/(z/2)+(y%(z/2))*2;
            ans=ans+x/z;
            if(x%z==0)
            ans--;
        }
        return ans;
    }
}
int main() {
    scanf("%d",&T);
    for(int i=1;i<=T;i++)
    {
        scanf("%d%d%d",&n,&m,&k);
        int a=work(n,m,k);
        printf("%d\n",a);
    }
 
    return 0;
}

交上去後,恭喜你,錯了,爲什麼錯了?
大家看看數據範圍:
1≤T≤10^6
1≤n,m≤10^18
2≤k≤10^18
10的18次方,你用int?!
再改改:

#include<bits/stdc++.h>
using namespace std;
int T;
long long n,m,k;
int work(long long x,long long y,long long z) {
    long long ans=0;
    long long sum=0;
    if(z%2==0)
    {
        sum=sum+y*2+x;
        if(sum%z==0)ans--;
        ans=ans+sum/z;
        return ans;
    }
    else
    {
        if(y/z*2>=x)
        {
            ans=ans+x;
            z--;
            z/=2;
            ans=ans+(y-x)/z;
            ans--;
        }
        else
        {
            ans=ans+(y)/(z/2);
            x=x-(y)/(z/2)+(y%(z/2))*2;
            ans=ans+x/z;
            if(x%z==0)
            ans--;
        }
        return ans;
    }
}
int main() {
    scanf("%d",&T);
    for(long long i=1;i<=T;i++)
    {
        scanf("%lld%lld%lld",&n,&m,&k);
        int a=work(n,m,k);
        printf("%d\n",a);
    }
 
    return 0;
}

還是錯了,博主在逗我吧我交上去的時候還是錯的,我實在不是道問題在哪了,於是,把變量a改爲了long long型,沒想到的是,竟然對了!
最終代碼:

#include<bits/stdc++.h>
using namespace std;
long long T;
long long n,m,k;
long long work(long long x,long long y,long long z) {
    long long ans=0;
    long long sum=0;
    if(z%2==0)
    {
        sum=sum+y*2+x;
        if(sum%z==0)ans--;
        ans=ans+sum/z;
        return ans;
    }
    else
    {
        if(y/z*2>=x)
        {
            ans=ans+x;
            z--;
            z/=2;
            ans=ans+(y-x)/z;
            ans--;
        }
        else
        {
            ans=ans+(y)/(z/2);
            x=x-(y)/(z/2)+(y%(z/2))*2;
            ans=ans+x/z;
            if(x%z==0)
            ans--;
        }
        return ans;
    }
}
int main() {
    scanf("%lld",&T);
    for(long long i=1;i<=T;i++)
    {
        scanf("%lld%lld%lld",&n,&m,&k);
        long long a=work(n,m,k);
        printf("%lld\n",a);
    }
 
    return 0;
}

好了,這題就到這裏了,打字好辛苦,請您點個贊。

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