GHOJ 421 硬币交换

题目描述

        小z最近迷上了一款游戏——To Be A Farmer,他在游戏中控制的人物是一个叫FZ的Farmer。FZ身上有G1个金币、S1个银币和B1个铜币,而他至少需要G2个金币、S2个银币和B2个铜币。为了完成这个目标,小z只好控制FZ来到了游戏中的银行。银行有如下规定:

        (1)你可以用1个金币交换9个银币;

        (2)你可以用11个银币交换1个金币;

        (3)你可以用1个银币交换9个铜币;

        (4)你可以用11个铜币交换1个银币;

        小z看到这些规定,顿时头都大了,只好求助于你。聪明的你来帮助他解决这样一个问题:最少需要交换多少次硬币才能至少拥有G2个金币、S2个银币和B2个铜币呢?

 

输入格式

        第一行包含三个整数,G1、S1和B1。

        第二行包含三个整数,G2、S2和B2。

        0≤G1、S1、B1、G2、S2、B2≤1000000。

输出格式

        如果可以完成任务的话,输出文件中应包含一个整数,表示最少交换次数;否则包含一个整数-1。

 

输入样例

10 0 0

0 0 81

输出样例

10

 

题解

        这里我们用$a,b,c$表示$g,s,b$。

        我们通过减少$b1$先让$a1,c1$达到$a2,c2$,此时我们只需要考虑$b1$是否能达到$b2$了。

        容易想到,如果要让次数尽可能少,那就要尽可能用$a1$来更新$b1$。

        我们按照先后顺序用$a1,c1$来更新$b1$,要求$a1,c1$都始终达到$a2,c2$,最后判断$b1$是否达到$b2$即可。

#include <iostream>

using namespace std;

int a1, b1, c1, a2, b2, c2;
int ans;

int main()
{
    cin >> a1 >> b1 >> c1 >> a2 >> b2 >> c2;
    if(a1 < a2)
    {
        ans += a2 - a1;
        b1 -= (a2 - a1) * 11;
        a1 = a2;
    }
    if(c1 < c2)
    {
        ans += (c2 - c1 + 8) / 9;
        b1 -= (c2 - c1 + 8) / 9;
        c2 += (c2 - c1 + 8) / 9 * 9;
    }
    if(b1 < b2 && a1 > a2)
    {
        if(b1 + (a1 - a2) * 9 < b2)
        {
            ans += (a1 - a2);
            b1 += (a1 - a2) * 9;
            a1 = a2;
        }
        else
        {
            ans += (b2 - b1 + 8) / 9;
            a1 -= (b2 - b1 + 8) / 9;
            b1 += (b2 - b1 + 8) / 9 * 9;
        }
    }
    if(b1 < b2)
    {
        if(b1 + (c1 - c2) / 11 >= b2)
        {
            ans += (c1 - c2) / 11;
            b1 += (c1 - c2) / 11;
            c1 -= (c1 - c2) / 11 * 11;
        }
    }
    cout << (b1 >= b2 ? ans : -1); 
    return 0;
}
参考程序
原文地址:https://www.cnblogs.com/kcn999/p/10800895.html