【问题标题】:C# : Currency Rendering SolutionC#:货币渲染解决方案
【发布时间】:2017-06-09 03:20:33
【问题描述】:

我必须为这个任务找到一个解决方案:

“超市越来越多地配备了自动收银机。这些资金中的大多数只接受信用卡支付,尽管很大一部分消费者仍然支付现金(用纸币和硬币)。

现金支付遇到的问题之一是货币的呈现:如何以最佳方式获得给定的金额,即使用最少数量的硬币和纸币?这是我们每个人每天都会遇到的问题,更不用说自动收银机了。

在这个练习中,我被要求尝试找到一个在特定情况下进行零钱的最佳解决方案:当自动收银机只包含 2 欧元硬币、5 欧元和 10 欧元纸币时。

为简化问题,我们将考虑所有这些硬币和纸币的数量都是无限的。

以下是一些货币示例:

金钱的回报由 Currency 对象表示。该物品有3个属性:piece2、billet5和billet10,分别存储2欧元、5欧元票和10欧元票的硬币数量。

例如,如果我们以表的示例 2(6 €)为例,我们应该得到一个 Money 对象:

  • Piece2 价值 3(3 件 2 €)
  • Ticket5 值 0(没有 5 欧元的票)
  • Ticket10 值 0(没有 10 欧元的票)

任务:实现 MonnaieOptimale(int s) 方法,该方法返回一个 Currency 对象,其中包含总和为 s 的硬币和纸币。如果无法返回币种(如示例1),则返回null。

为了达到最佳效果,解决方案总是必须尽可能以最少数量的硬币和门票进行更改。”

数据:s 始终是小于或等于 9223372036854775807 的严格正整数(长整数)

解决方案的一般结构如下:

建议??

【问题讨论】:

  • 你可以用简单的数学自组织算法来解决它,因为你事先知道了名目。只需“在纸上”解决它,您就会明白如何在 C# 中解决它。附言如果事先不知道名词,则可以使用动态规划解决问题,但需要O(s) 时间,这对您的情况来说是不够的。
  • 提示:当您需要将其增加到 10 时,使用名义 2 或名义 5 的硬币从不最佳,因此每 N 使用 10*N .
  • 统一分配?
  • “实现 MonnaieOptimale(int s) 方法,该方法返回一个包含总和为 s 的硬币和纸币的货币对象”似乎是问题中已经存在的可靠建议。
  • 到目前为止你尝试过什么?另外,请不要发布代码图像,将其发布为文本。另外,你能改进问题本身的措辞吗?请看:Why is “Can someone help me?” not an actual question?

标签: c# .net algorithm


【解决方案1】:

首先,简单的贪心方法(总是得到最大的,即 10)在这里不起作用,因为系统不是规范的,考虑s = 11,如果你使用硬币 10,你会得到“不可能”,但有可能{ 5, 2, 2, 2 }。

我在这里有一个稍微不同的想法,使用奇数/偶数的奇偶校验:

  1. 如果s 是偶数,则采用贪婪方法,但从不使用硬币 5
  2. 如果s 是奇数,继续使用硬币5 直到s 变成偶数,然后执行步骤1。

例如:s = 18,解决方案 = { 10, 2, 2, 2, 2 }。 s = 23, 解决方案 = { 5, 10, 2, 2, 2, 2 }

它为什么起作用,是因为人们可以注意到,对于硬币系统 { 2, 10 },您可以使用贪婪方法制作任何偶数 s(它是偶数域的规范)。

再加上任何奇数减去另一个奇数都会得到偶数,因此对于奇数s,我们可以使用一枚硬币 5 使s 成为偶数以减少问题。

根据这个逻辑,我认为任何s 最多可以使用一个5 硬币,并且只有当s = 1 or 3 的答案是“不可能”时

【讨论】:

    【解决方案2】:

    我是这样手动解决的:

    public static Monnaie MonnaieOptimale(long s)
            {
                if (s<10)
                {
                    if (s%2 =0) {Monnaie.billet10 = 0 ; Monnaie.billet5 = 0 ; Monnaie.piece2 = s/2 }
                    else if (s == 5)  {Monnaie.billet10 = 0 ; Monnaie.billet5 = 1 ; Monnaie.piece2=0 }
                    else if (s == 7)  {Monnaie.billet10 = 0 ; Monnaie.billet5 = 1 ; Monnaie.piece2=1  }
                    else Monnaie.billet10 = 0 ; Monnaie.billet5 = 1 ; Monnaie.piece2= 2
                }
    
                else
                {
                    if (s%2 =0) 
                    {
                        Monnaie.billet10 = Math.Floor(s/10);
                        if ((Monnaie.billet10 * 10) != s) {Monnaie.billet5 = 0 ; Monnaie.piece2= (s%10)/2 }
                    }
                    else
                    {
                        private lastDigit = s%10;
                        if (lastDigit ==1){Monnaie.billet10 = ((s/10)-1) ; Monnaie.billet5 = 0 ; Monnaie.piece2=3 }
                        else if (lastDigit ==3){Monnaie.billet10 = ((s/10)-1) ; Monnaie.billet5 = 0 ; Monnaie.piece2=4 }
                        else if (lastDigit ==5){Monnaie.billet10 = (s/10) ; Monnaie.billet5 = 1 ; Monnaie.piece2=0 }
                        else if (lastDigit ==7){Monnaie.billet10 = (s/10) ; Monnaie.billet5 = 1 ; Monnaie.piece2=1}
                        else {Monnaie.billet10 = (s/10) ; Monnaie.billet5 = 1 ; Monnaie.piece2=2}
                    }
    
                }
    
            }
    

    【讨论】:

      【解决方案3】:
      using System;    
      public class Program {    
      public static void Main() {    
      int re10 = 0, re5 = 0, re2 = 0, s = 197;     
      while (s / 2 != 0) {          
          while (s / 5 != 0) {    
              while (s / 10 != 0) {    
                   if (s % 10 % 5 == 0) {    
                        re10 = s / 10;    
                        s = s % 10;    
                           }   
                    else {    
                    if (s / 10 > 1) {    
                     re10 = s / 10 - 1;    
                     s = s % 10 + 10;    
                    }    
                    break;    
                   }    
                 }    
              if (s % 5 % 2 == 0) {    
                   re5 = s / 5;    
                   s = s % 5;    
                  } else    
              if (s / 5 > 1) {    
               re5 = s / 5 - 1;    
               s = s % 5 + 5;    
              }    
              break;    
             }    
        re2 = s / 2;    
         s = s % 2;    
        }    
      if(re5==3){re10+=1;re5-=2;}
       Console.WriteLine("billet 10 :" + re10);    
       Console.WriteLine("billet 5 :" + re5);    
       Console.WriteLine("billet 2 :" + re2);    
       Console.WriteLine("Total : "re2 * 2 + re10 * 10 + re5 * 5);     
       }    
      }    
      
      billet 10 :18
      billet 5 :3
      billet 2 :1
      Total :  197
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-12
        • 2015-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-21
        相关资源
        最近更新 更多