HDU 1288 Hat's Tea

Hat's Tea

Problem Description
Hat is a member of PG Studio. Hat codes a lot and so he often buys tea at tea vending machine. But the tea vending machine just eat coins and spit out tea, if you feed the machine more coins than the tea’s price and the machine will not spit out your change. 
Your program will be given numbers and types of coins Hat has and the tea price. The tea vending machine accepts coins of values 1, 5, 10 RMB (Jiao). The program should output which coins Hat has to use paying the tea so that he uses as many coins as possible. 

Input
Each line of the input contains four integer numbers separated by a single space describing one situation to solve. The first integer on the line N, , is the tea price in Jiao. Next four integers , , are the numbers of YiJiao (1 Jiao.RMB), WuJiao (5 Jiao.RMB), and ShiJiao (10 Jiao.RMB) in Hat's valet. The last line of the input contains four zeros and no output should be generated for it. 
 
Output
For each situation, your program should output one line containing the string " T1 YiJiao, T2 WuJiao, and T3 ShiJiao ", where T1, T2, T3 are the numbers of coins of appropriate values Hat should use to pay the tea while using as many coins as possible. If Hat does not have enough coins to pay the tea exactly, your program should output "Hat cannot buy tea.”.

Sample Input
6653 226 72 352 
578 5 127 951
0 0 0 0 

Sample Output
Hat cannot buy tea.
3 YiJiao, 115 WuJiao, and 0 ShiJiao
分析:主要满足两个条件 1:刚好等于茶价格。2:硬币尽可能的多。 
AC代码+题解
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
    int  ans,a,b,c;//a,b,c分别为拥有一角,五角,十角的个数
    while(scanf("%d %d %d %d",&ans,&a,&b,&c),a+b+c+ans)
    {
     int y=0,w=0,s=0;//y,w,s分别为需要使用一角,五角,十角的个数
     if( ans>a+b*5+c*10 || ans%5>a || ans%10>b*5+a ) puts("Hat cannot buy tea.");
     //将这些钱不能组成ans情况全部排除,那么else里面就一定是可以组成的情况,下面一一解释每一条不能组成的理由
     //ans>a+b*5+c*10  如果拥有的钱数总额小于要支付金额,不能购买
     //ans%5>a   很显然出现了1~4角只能用1角面值的币去购买,如果1角的币不够,不能购买
     //ans%10>b*5+a   这一条是检测5角面值的币数量够不够的,比如输入 27 2 0 30,此情况是不能购买的,因为没有5角面值
     else
     {
         //本题包含贪心思想,就是想用尽量使币的数量多,如果能用5个1角去买,就别用1个5角
         if(a>=ans) y=ans;  //如果1角的币够支付,则全用一角的币支付
         else
         {
             y=ans%5+(a-ans%5)/5*5;  //如果1角的币不够支付所有,则支付1~4的零头外,还要以每5个币组成一个5角进行支付,因为把零头减去后,剩下的金额是可以整除5的
             ans-=y;   //还剩多少没有支付
             if(b*5>=ans) w=ans/5,ans-=w*5;  //如果剩下的金额能用5角的全支付,则用5角的全部支付
             else
             {
                 w=b;    //如果5角的不够支付所以,则先把5角的全花完,即w=b;
                 ans-=w*5;  //剩下未支付的金额
                 if(ans%10==5)   //这个判断非常重要,如果剩下的金额尾数是5,现在的币只有10角的,肯定不能支付,所以肯定要减少一个5角的面值或减少5个1角的面值
                 {
                     if(w>0) w--;  //如果支付的5角面值个数不为0,则减去一个5角面值的币
                     else y-=5;    //否则减去5个1角面值的币
                     ans+=5;     //币已减去,余额要加上来嘛
                     //  看了很多种题解,if else多的不想看,我觉得还是我的代码简短些,思路也清楚些,之前是没有这段分支,所以一直wa
                 }
                 s=ans/10;   //剩下的就给10角来支付咯
                 ans-=s*10;
             }
          }
           printf("%d YiJiao, %d WuJiao, and %d ShiJiao
",y,w,s);
       }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/www-cnxcy-com/p/7170329.html