首页 > 代码库 > [codechef July Challenge 2017] Calculator

[codechef July Challenge 2017] Calculator

CALC: 计算器
题目描述
大厨有一个计算器,计算器上有两个屏幕和两个按钮。初始时每个屏幕上显示的都是 0。每按
一次第一个按钮,就会让第一个屏幕上显示的数字加 1,同时消耗 1 单位的能量。
每按一次第二个按钮,会让第二个屏幕上显示的数字加上第一个屏幕上显示的数字,同时消
耗 B 单位的能量。
初始时,计算器有 N 单位的能量。大厨想知道在能量限制下,第二个屏幕上最大可以出现的
数字是多少?
输入格式
输入的第一行包含一个整数 T,代表测试数据的组数。接下来是 T 组数据。
每组数据仅有一行,包含两个整数 N 和 B。
输出格式
对于每组数据,输出一行,包含一个整数,代表所求的答案。
数据范围和子任务
? 1 ≤ T ≤ 10, 000
? 1 ≤ N, B ≤ 1, 000, 000, 000
子任务 1(20 分):
? 1 ≤ N, B ≤ 1, 000
子任务 2(80 分):
? 无附加限制
样例数据
输入
3
10 2
8 5
6 1
输出
12
3
9
样例解释
对于第一组数据,可以使用 10 单位的能量,按一次第二个按钮耗费 2 单位的能量。大厨可以
按照下面的方案操作:

技术分享

 

我们假设按了x次一号按钮,y次二号按钮,则由贪心的想法(即现一次性按完按钮1,再按完按钮2)得知x,y满足:

x+By=N,求x*y的最大值。

则x=N-By,折ans=x*y,则ans= -By^2+Ny

这是一个二次函数,顶点在-b/2a,也就是 N/2B。由于x,y是整数,所以除了取x=N/2B,还要取x=N/2B-1,x=N/2B+1等算一下(因为顶点不一定就是整点)。

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 #include<string>
 6 using namespace std;
 7 int main(){
 8     int T; scanf("%d",&T);
 9     for (; T; T--){
10         long long N,B; scanf("%lld%lld",&N,&B);
11         long long y=N/(2*B),x;
12         long long ans=(-B*y+N)*y;
13         x=y-1,ans=max(ans,(-B*x+N)*x);
14         x=y,ans=max(ans,(-B*x+N)*x);
15         x=y+1,ans=max(ans,(-B*x+N)*x);
16         printf("%lld\n",ans);
17     }
18     return 0;
19 } 
View Code

 

[codechef July Challenge 2017] Calculator