zoukankan      html  css  js  c++  java
  • 【HDU-4803】【2013ACM/ICPC亚洲区南京站现场赛】 A

    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?

    Input
    There are several (about 50, 000) test cases, please process till EOF.
    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 +

  • 相关阅读:
    态度决定你的人生高度(一个人能否成功,就看他的态度)
    要取得成功,必须有所牺牲:职场超级成功秘诀
    28位世界名人得到过的最佳忠告(仔细体味,获益匪浅)
    你可知道
    不要把失败的责任推给你的命运,你距离你的目标有多远
    一个人凭什么自信?认识自我—你就是一座金矿
    试一下,把你的生命折叠51次 相信你会得到成功的厚度
    赠鹰飞道扬(帮别人名字作诗)
    魏海燕(帮别人名字作诗)
    职场有感
  • 原文地址:https://www.cnblogs.com/Vikyanite/p/12181935.html
Copyright © 2011-2022 走看看