Смена монет в C# с ограниченным количеством монет
Я построил следующую замену монет (C#), которая отлично работает:
class Program
{
static int amount = 0;
static void Main(string[] args)
{
EnterAmount();
int[] coins = new int[] { 500, 100, 50, 20, 10, 5, 2, 1 };
int Results = 0;
for (int i = 0; i < coins.Length; i++)
{
Results = amount / coins[i];
Console.WriteLine(Results + " x " + coins[i]);
amount -= Results * coins[i];
}
}
static void EnterAmount()
{
Console.Out.WriteLine("Enter an amount : ");
amount = int.Parse(Console.ReadLine());
}
}
Моя проблема в том, что я не знаю, как ограничить количество монет для каждой монеты. Например, я хотел бы иметь максимальное количество: 4 монеты по 500 евро, 6 монет по 10 евро, 5 монет по 2 евро и т. Д. И было бы здорово, если бы обмен монет вернул количество монет, использованных для каждой монеты.,
Не могли бы вы мне помочь? Спасибо.
2 ответа
Имейте в виду, что этот код просто отвечает на ваш вопрос о том, кому ограничивать количество монет, но ваш алгоритм неполон, поскольку вы не учитываете много угловых случаев.
static void Main(string[] args)
{
var amount = 100000;
var availabeCoins = new CoinPack[]
{
new CoinPack { Value = 500, Amount = 2 },
new CoinPack { Value = 100, Amount = 3 },
new CoinPack { Value = 50, Amount = 5 },
new CoinPack { Value = 20, Amount = 1 },
new CoinPack { Value = 10, Amount = 2 },
new CoinPack { Value = 5, Amount = 0 },
new CoinPack { Value = 2, Amount = 10 },
new CoinPack { Value = 1, Amount = 500 }
};
var usedCoins = new CoinPack[]
{
new CoinPack { Value = 500 },
new CoinPack { Value = 100 },
new CoinPack { Value = 50 },
new CoinPack { Value = 20 },
new CoinPack { Value = 10 },
new CoinPack { Value = 5 },
new CoinPack { Value = 2 },
new CoinPack { Value = 1 }
};
for (int i = 0; i < availabeCoins.Length; i++)
{
usedCoins[i].Amount = amount / availabeCoins[i].Value;
if (usedCoins[i].Amount > availabeCoins[i].Amount)
{
usedCoins[i].Amount = availabeCoins[i].Amount;
}
amount -= usedCoins[i].Amount * usedCoins[i].Value;
}
foreach (var usedCoin in usedCoins)
{
Console.WriteLine(usedCoin.Value + " " + usedCoin.Amount);
}
}
class CoinPack
{
public int Value;
public int Amount;
}
UPD Это решение довольно неэффективно, но, думаю, оно решит вашу проблему. Вы можете взять это как справку и улучшить это самостоятельно.
void Main(string[] args)
{
var amount = 6;
var availabeCoins = new List<CoinPack>
{
new CoinPack { Value = 500, Amount = 0 },
new CoinPack { Value = 100, Amount = 0 },
new CoinPack { Value = 50, Amount = 0 },
new CoinPack { Value = 20, Amount = 0 },
new CoinPack { Value = 10, Amount = 0 },
new CoinPack { Value = 5, Amount = 1 },
new CoinPack { Value = 2, Amount = 3 },
new CoinPack { Value = 1, Amount = 0 }
};
var usedCoins = new List<CoinPack>
{
new CoinPack { Value = 500, Amount = 0 },
new CoinPack { Value = 100, Amount = 0 },
new CoinPack { Value = 50, Amount = 0 },
new CoinPack { Value = 20, Amount = 0 },
new CoinPack { Value = 10, Amount = 0 },
new CoinPack { Value = 5, Amount = 0 },
new CoinPack { Value = 2, Amount = 0 },
new CoinPack { Value = 1, Amount = 0 }
};
if (Change(amount, availabeCoins, usedCoins) != null)
{
foreach (var usedCoin in usedCoins)
{
Console.WriteLine(usedCoin.Value + " " + usedCoin.Amount);
}
}
else
{
Console.WriteLine("Cannot find exact change");
}
}
List<CoinPack> Change(int amount, List<CoinPack> availableCoins, List<CoinPack> usedCoins)
{
if (amount == 0)
{
return availableCoins;
}
if (amount < 0)
{
return null;
}
foreach (var availableCoin in availableCoins.Where(ac => ac.Amount > 0 && amount >= ac.Value))
{
var newAvailableCoins = CopyCoins(availableCoins);
newAvailableCoins.First(c => c.Value == availableCoin.Value).Amount--;
var change = Change(amount - availableCoin.Value, newAvailableCoins, usedCoins);
if (change == newAvailableCoins)
{
usedCoins.First(c => c.Value == availableCoin.Value).Amount++;
return availableCoins;
}
}
return null;
}
List<CoinPack> CopyCoins(List<CoinPack> coinPacks)
{
var copy = new List<CoinPack>();
foreach (var coinPack in coinPacks)
{
copy.Add(new CoinPack { Value = coinPack.Value, Amount = coinPack.Amount });
}
return copy;
}
class CoinPack
{
public int Value;
public int Amount;
}
Я думаю, что это будет полезно
using System;
using System.Data;
using System.IO;
namespace ConsoleApplicationTests
{
class Program
{
static int amount = 321370;
static void Main(string[] args)
{
Coin[] c = new Coin[] { new Coin(500, 7), new Coin(200, 3), new Coin(100, 5) ,
new Coin(50, 6), new Coin(20, 2), new Coin(10, 4),
new Coin(5, 0), new Coin(2, 5), new Coin(1, 3)};
int netAmount = amount;
for (int i = 0; i < c.Length; i++)
{
amount -= c[i].coveredPrice(amount);
}
for (int i = 0; i < c.Length; i++)
{
Console.WriteLine(c[i].ToString());
}
Console.ReadLine();
}
}
class Coin
{
private int price;
private int counted; // You can continue your bank for next amount too.
private int maxNo;
public Coin(int coinPrice, int coinMaxNo)
{
this.price = coinPrice;
this.maxNo = coinMaxNo;
this.counted = 0;
}
public int coveredPrice(int Price)
{
int Num = Price / price;
if (maxNo == 0)
return 0;
if (maxNo != -1) //-i is infinit
if (Num > this.maxNo - this.counted)
Num = maxNo;
this.counted += Num;
return Num * price;
}
//public int getPrice() { return this.price; }
//public int getCount() { return this.counted; }
//public int getMax() { return this.maxNo; }
public override string ToString()
{
return string.Format("{0} x {1} (max {2}) ", this.price.ToString(), this.counted.ToString(), this.maxNo.ToString());
}
}
}