using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
//10个试剂
var materialList = new List<Material>();
for (int i = 0; i < 5; i++)
{
var material = new Material()
{
Code = i + 1,
Name = "Material" + (i + 1).ToString(),
Price = (i + 1),
};
materialList.Add(material);
material.QtyList = new List<int>();
int j = 1;
//最多取20个
while (j <= 5)
{
material.QtyList.Add(j);
j++;
}
}
Console.WriteLine($"MaterialList = {Newtonsoft.Json.JsonConvert.SerializeObject(materialList)}");
decimal total = 0;
int totalAmount = 70;
bool flag = false;
var diffList = new List<Diff>();
plus(new Diff(), materialList, diffList, totalAmount, total, ref flag);
var diff = diffList.OrderBy(p => p.DiffAmt).FirstOrDefault();
Console.ReadLine();
}
public static void plus(Diff diff, List<Material> materialList, List<Diff> diffList, decimal totalAmount, decimal total, ref bool flag)
{
if (flag)
return;
if (materialList != null && materialList.Any())
{
var material = materialList.First();
var list = materialList.Where(p => p.Code != material.Code).ToList();
foreach (var qty in material.QtyList)
{
if (flag)
break;
if (totalAmount >= material.Price * qty + total)
{
var oldTotal = total;
oldTotal += material.Price * qty;
UpdateDiff(diff, material.Code, qty);
if (list.Any())
plus(diff, list, diffList, totalAmount, oldTotal, ref flag);
else
{
diff.DiffAmt = totalAmount - oldTotal;
diffList.Add(DeepCopy(diff));
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(diff));
if (diff.DiffAmt == 0)
{
flag = true;
break;
}
}
}
}
}
}
/// <summary>
/// 深度拷贝对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <returns></returns>
public static T DeepCopy<T>(T obj)
{
object retval;
using (MemoryStream ms = new MemoryStream())
{
XmlSerializer xml = new XmlSerializer(typeof(T));
xml.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
retval = xml.Deserialize(ms);
ms.Close();
}
return (T)retval;
}
public static void UpdateDiff(Diff diff, int index, int qty)
{
var propName = "Number" + index.ToString();
if (diff.GetType().GetProperty(propName) != null)
{
diff.GetType().GetProperty(propName).SetValue(diff, qty);
}
}
public static void showLog(List<int> list)
{
string str = string.Join(",", list.ToArray());
Console.WriteLine(str);
}
}
public class Material
{
public int Code { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public int Qty { get; set; }
public List<int> QtyList { get; set; }
}
public class Diff
{
public int Number1 { get; set; }
public int Number2 { get; set; }
public int Number3 { get; set; }
public int Number4 { get; set; }
public int Number5 { get; set; }
public int Number6 { get; set; }
public int Number7 { get; set; }
public int Number8 { get; set; }
public int Number9 { get; set; }
public int Number10 { get; set; }
public decimal DiffAmt { get; set; }
}
}