【HDU-4803】【2013ACM/ICPC亚洲区南京站现场赛】 A - Poor Warehouse Keeper
作者:互联网
Jenny is a warehouse keeper. He writes down the entry records everyday. The record is shown on a screen, as follow:
There
are only two buttons on the screen. Pressing the button in the first
line once increases the number on the first line by 1. The cost per unit
remains untouched. For the screen above, after the button in the first
line is pressed, the screen will be:
The exact total price is 7.5, but on the screen, only the integral part 7 is shown.
Pressing
the button in the second line once increases the number on the second
line by 1. The number in the first line remains untouched. For the
screen above, after the button in the second line is pressed, the screen
will be:
Remember the exact total price is 8.5, but on the screen, only the integral part 8 is shown.
A new record will be like the following:
At that moment, the total price is exact 1.0.
Jenny expects a final screen in form of:
Where x and y are previously given.
What’s the minimal number of pressing of buttons Jenny needs to achieve his goal?
Each test case contains one line with two integers x(1 <= x <= 10) and y(1 <= y <= 109) separated by a single space - the expected number shown on the screen in the end. Output For each test case, print the minimal number of pressing of the buttons, or “-1”(without quotes) if there’s no way to achieve his goal. Sample Input 1 1 3 8 9 31 Sample Output 0 5 11 Hint For the second test case, one way to achieve is: (1, 1) -> (1, 2) -> (2, 4) -> (2, 5) -> (3, 7.5) -> (3, 8.5)
简单的讲一下思路吧。首先第一点你要看懂题目到底是什么意思,最关键的是按下第一个按钮是什么意思。
按下第一个按钮会让第一行的数字+1,之后第二行的数字会加上(第二行数字/+1之前的第一行的数字)
按下第二个按钮会让第二行的数字+1
具体看下面这个例子:
(1, 1) ---按下第二个按钮-----> (1, 1+1) = (1, 2) -----按下第一个按钮------> (2, 2 + 2 / 1) = (2,4)-----按下第二个按钮--------> (2, 4+1) = (2, 5) ----按下第一个按钮-------> (2+1, 5 + 5 / 2) = (3, 7.5)------按下第二个按钮--------> (3, 7.5 +1) = (3,8.5)
弄清楚题意之后我们观察数据,发现x是<=10的,那么解题的关键就必然落在x上。
我们发现第一个按钮所要按下的次数是一定的,一定为x-1。
那么发现,我们假设按下第一个按钮前,按下Ci次的第二个按钮(i∈[1,x])。
那么可以得到关于Ci(i∈[1, x])的线性式子。
下面是推导过程。
因为最后的总次数cnt应该是等于X-1+ ∑Ci。之后每个Ci之前的系数是递减的。(X*C1, X/2*C2, X/3*C3··· )
那么当cnt取到最小时,每个Ci都应该取到最大才对。
这样计算每个Ci就只需要将Ci-1减去之后除以Ci的系数,之后取上限和取下限,判断哪个最优即可。
那么就有了以下AC代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 1e5+5; int main() { std::ios::sync_with_stdio(false); int X, Y; int cnt = 0; while (cin >> X >> Y) { double cha = Y-X; int cnt = X - 1; //千万要注意b < a的情况 if (cha < 0) { cout << -1 << endl; continue; } for (int i = 1; i <= X; i++) { //关于这里先取上限是因为我们要满足当前Ci要尽量大的情况 int Ci_floor = floor((cha)/((double)X/i)); int Ci_ceil = ceil((cha)/((double)X/i)); if (cha - Ci_ceil * ((double)X / i) > -1) cnt += Ci_ceil, cha -= Ci_ceil * ((double)X / i); else cnt += Ci_floor, cha -= Ci_floor * ((double)X / i); } cout << cnt << endl; } return 0; }
Y = X +
标签:2013ACM,南京站,HDU,screen,Ci,number,按下,按钮,line 来源: https://www.cnblogs.com/Vikyanite/p/12181935.html