zoukankan      html  css  js  c++  java
  • Wannafly交流赛1_B_硬币【数学】

    Wannafly交流赛1_B_硬币【数学】

    链接:https://www.nowcoder.com/acm/contest/69/B
    来源:牛客网

    题目描述
    蜥蜴的生日快到了,就在这个月底!
    今年,蜥蜴的快乐伙伴之一壁虎想要送好多个1元硬币来恶整蜥蜴。
    壁虎身上目前有的硬币种类和数量如下:
    c1个1元硬币、c5个5元硬币、c10个10元硬币、c50个50元硬币。
    壁虎觉得只送c1个1元硬币不够慷慨,想拿一些币值较大的硬币去换更多的1元硬币,于是跑去找一台自动贩卖机,靠着买东西找零来获得更多1元硬币!
    这台自动贩卖机的找零机制如下:
    每件物品的价格都是v元(v为给定值),假设你投入的硬币总额是x元(x必须>=v),点选了一样物品后,贩卖机就会落下x-v元。
    假设落下的硬币有d1个1元硬币、d5个5元硬币、d10个10元硬币、d50个50元硬币,贩卖机会选择d1+d5+d10+d50最小的方案找你钱,有办法证明这样的方案只有一种。(假设此自动贩卖机每种币值的硬币都有无穷多个。)
    现在壁虎想知道,和这台自动贩卖机换钱后(假设壁虎心甘情愿地花巨量时间来买很多用不到的东西来恶整蜥蜴),最多能用多少1元硬币恶整蜥蜴?
    输入描述:

    输入的第一行有一个正整数T,代表询问数。
    接下来有T行,每个询问各占1行,包含五个整数c1,c5,c10,c50,v,分别代表壁虎有的1元、5元、10元、50元的硬币数目以及此自动贩卖机里一件物品的价格。

    输出描述:

    每个询问请输出一行包含一个整数,代表该询问的答案。

    示例一
    输入

    2
    2 0 1 0 3
    0 0 0 1 10

    输出

    6
    0

    说明

    在第一个询问中,你共有2个1元硬币和1个10元硬币,自动贩卖机中一个物品的价格为3元。
    首先壁虎可以投一个10元硬币买一件物品,此时贩卖机会找壁虎1个5元和2个1元,之后壁虎再投一个5元买一件物品,贩卖机会再找壁虎2元,于是最后壁虎共有6个1元硬币。

    备注:

    1<=T<=104
    0<=c1,c5,c10,c50<=109
    1<=v<=109

    思路
    假如模拟一遍,就可能因为数据量庞大还TLE;
    其实我们可以想想,放进去的50 10 元 最终都会变成 5元 和 1元

    那么我们不妨假设 刚开始我们就把所有的50元和10元都变成5元放进去。然后将所有的钱都放进去。每买一件物品,换出的钱币必然是5的余数,所以我们可以知道 买一件物品 所能换得的1元硬币数是 (5 - v % 5) % 5
    然后再求一下换几次就好了 最后就能求得换得的总的1元硬币数

    AC代码

    #include <iostream>       //数学方法 
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <deque>
    #include <vector>
    #include <queue>
    #include <string>
    #include <cstring>
    #include <map>
    #include <stack>
    #include <set>
    #include <cstdlib>
    #include <ctype.h>
    #include <numeric>
    #include <sstream>
    using namespace std;
    typedef long long LL;
    const double PI  = 3.14159265358979323846264338327;
    const double E   = 2.718281828459;  
    const double eps = 1e-6;
    const int MAXN   = 0x3f3f3f3f;
    const int MINN   = 0xc0c0c0c0;
    const int maxn   = 1e5 + 5; 
    const int MOD    = 1e9 + 7;
    LL c[4], a[4] = {1, 5, 10, 50};
    LL m, v;
    int main()
    {
        int t;
        cin >> t;
        while (t--)
        {
            int c1, c5, c10, c50, v;
            scanf("%d%d%d%d%d", &c1, &c5, &c10, &c50, &v);
            LL ans = c1;
            LL tot = 0;
            LL sum = 1LL * c5 *5 + 1LL * c10 *10 + 1LL * c50 * 50;
            int add = (5 - v % 5) % 5;
            int tmp = add + v;
            if (add == 0)
                cout << ans << endl;
            else
            {
                LL cnt = sum / tmp;
                cout << ans + add * cnt << endl;
            }
        }
    }
  • 相关阅读:
    整除
    奇怪的生日礼物
    欧拉函数平方和
    奇怪的生日礼物(数论基础)
    整除(简单数论)
    Tarjan求割点
    构造双连通(tarjan)
    次小生成树
    机器扫边
    最短路径(树形DP)
  • 原文地址:https://www.cnblogs.com/Dup4/p/9433393.html
Copyright © 2011-2022 走看看