---
title: Calculator
tags:
  - Greedy
id: "1142"
categories:
  - - OI
    - Common Skill
date: 2017-07-11 23:10:10
---

## 题目描述

Chef has a calculator which has two screens and two buttons. Initially, each screen shows the number zero. Pressing the first button increments the number on the first screen by $1$, and each click of the first button consumes $1$ unit of energy.

Pressing the second button increases the number on the second screen by the number which is currently appearing on the first screen. Each click of the second button consumes $B$ units of energy.

Initially the calculator has $N$ units of energy.

Now chef wonders what the maximum possible number is, that he gets on the second screen of the calculator, with the limited energy.

## 题意概述

有两个按钮和两个初始为$0$的数字，按下第一个按钮可以消耗$1$单位能量使第一个数字加$1$，按下第二个按钮可以消耗$B$单位能量使第二个数字加上第一个数字。总共有$N$单位能量，问第二个数字最大能达到多少。

数据范围：$1 \le N, B \le 10^9$。

## 算法分析

根据贪心策略，按第一个按钮的操作一定在按第二个按钮的操作之前（否则交换一下顺序一定能得到更优解）。设按下第一个按钮$x$次，则第二个数字$y={N-x \over B}x$，对称轴为$x={N \over 2}$。令$a={N-x \over B}$，当$x={N \over 2}$时$a={N \over 2B}$。由于$a$是整数（否则会造成能量浪费），因此只需计算$a=\left\lfloor {N \over 2B} \right\rfloor$和$a=\left\lceil {N \over 2B} \right\rceil$时$y$的值，取较大者即可。

## 代码

```cpp
#include <iostream>
#include <cmath>
using namespace std;
long long T, n, b, p, q, x, ans;
long double k;
int main()
{
  cin >> T;
  while (T--) {
    cin >> n >> b;
    ans = 0;
    k = 1.0 * n / 2 / b;
    p = floor(k), q = ceil(k);
    x = n - b * p;
    if (x > 0 && x < n) ans = max(ans, p * x);
    x = n - b * q;
    if (x > 0 && x < n) ans = max(ans, q * x);
    cout << ans << endl;
  }
  return 0;
}
```
