链接: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;
}
好了,这题就到这里了,打字好辛苦,请您点个赞。
- 点不点赞?
- 点赞
- 不点赞