鏈接: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;
}
好了,這題就到這裏了,打字好辛苦,請您點個贊。
- 點不點贊?
- 點贊
- 不點贊