下图是一个装备系统的合成图谱,箭头指向的是合成之后的装备,每合成一个装备需要消耗一些金币(标注在矩形框里面),箭头上的数字表示合成所需的材料数量。比如,要合成n个装备A,需要消耗3n个装备B、1n个装备C、4n个装备D,而且还需要消耗26n金币(装备B和装备D的合成与此类似)。
为了简单起见,下面题目的装备图谱是一棵多叉树,而且玩家最初只拥有指定数量的叶子节点的装备,也就是图中的装备C、装备E、装备F和装备G。
注意,下面的图谱只是一个例子,作答的时候不要局限于这个图谱。
已知玩家拥有一些初级装备(叶子节点的装备)和n个金币,并且所有装备的合成都需要消耗金币,玩家需要合成尽可能多的某个装备(记为装备X),请用C#语言计算出玩家最多可以合成出多少个装备X。
请在收到题目的一至两天内完成,提交的时候只需要提交源代码。为了规范输入输出,下面给出代码的基本结构,作答的时候不要修改Run函数的函数原型。
此题以被我写成程序啦!这里附上运行的两张图
以下是代码:
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
public class CountNum : MonoBehaviour
{
public MaterialData materA, materB, materC, materD, materE, materF, materG;
public int Ccount,Ecount, Fcount, Gcount, TotoalCoin;
public ItemData itemDataA;
public InputField[] inputFields;
public Dropdown dropdown;
public string DropdownValue = "A";
public Text text1, text2;//1.成功合成装备件数,2.合成后剩余金币
void Start()
{
inputFields[0].onValueChanged.AddListener(delegate { Ecount = int.Parse(inputFields[0].text); });
inputFields[1].onValueChanged.AddListener(delegate { Fcount = int.Parse(inputFields[1].text); });
inputFields[2].onValueChanged.AddListener(delegate { Ccount = int.Parse(inputFields[2].text); });
inputFields[3].onValueChanged.AddListener(delegate { Gcount = int.Parse(inputFields[3].text); });
inputFields[4].onValueChanged.AddListener(delegate { TotoalCoin = int.Parse(inputFields[4].text); });
dropdown.onValueChanged.AddListener(delegate { DropdownValue = dropdown.options[dropdown.value].text; });
}
public class MaterialData
{
public ItemData item; //合成所需的物品
public int count; //合成所需的该物品的数量
}
public class ItemData
{
public int id; //物品 ID
public int count; //当前拥有的物品数量
public int costGold; //合成该物品所需的金币
public List<MaterialData> materialList; //合成该物品所需的材料
}
public void StartToRun()
{
CreatMater();
switch (DropdownValue)
{
case "A":
int n = Run(itemDataA, TotoalCoin);
text1.text = n.ToString();
text2.text = TotoalCoin.ToString();
Debug.Log("最多可合成数:"+n);
break;
case "B":
Debug.Log("最多可合成数:" + Run(materB.item, TotoalCoin));
break;
case "D":
Debug.Log("最多可合成数:" + Run(materD.item, TotoalCoin));
break;
}
inputFields[0].text = "0";
inputFields[1].text = "0";
inputFields[2].text = "0";
inputFields[3].text = "0";
inputFields[4].text = "0";
}
/// <summary>
/// 计算用 totalGold 金币最多可以合成的 item 装备的数量
/// </summary>
/// <param name="item">要合成的装备</param>
/// <param name="totalGold">拥有的金币</param>
/// <returns>可合成的 item 装备的最大数量</returns>
public int Run(ItemData item, int totalGold)
{
TotoalCoin = totalGold;
bool IsEasyModle = true;
int count = item.materialList.Count;
if (count == 0)//判断装备是否可合成
{
return item.count;
}
for (int i = 0;i< item.materialList.Count;i++)//初步判断复杂度,并且根据复杂度改变算法
{
if (item.materialList[i].item.costGold > 0)//若所需子物体可合成
{
IsEasyModle = false;
}
}
if (IsEasyModle)//简易算法
{
int MaxCount = TotoalCoin / item.costGold;//无视基础装备数的情况下可合成的最大个数
for (int i = 0;i<item.materialList.Count;i++)
{
if(item.materialList[i].item.count/ item.materialList[i] .count < MaxCount)//若所需物体小于最大可合成数
{
MaxCount = item.materialList[i].item.count / item.materialList[i].count;
}
}
TotoalCoin -= MaxCount * item.costGold;
return MaxCount;//返回可合成item最大值
}
else//复杂算法
{
int MaxCount = 0;
bool Isfinsh = false;
while (!Isfinsh & TotoalCoin > item.costGold)//若总金币大于合成目前物体所需金币,开始遍历运算
{
for (int i = 0;i< item.materialList.Count;i++)
{
if (item.materialList[i].item.count < item.materialList[i].count)//若合成一次所需物体数量不足
{
if (TotoalCoin >= item.materialList[i].item.costGold*(item.materialList[i].count - item.materialList[i].item.count) + item.costGold)//剩余金币足够合成材料费用
{
int num = item.materialList[i].count - item.materialList[i].item.count;
for (int x = 0;x < num; x++)//合成X个所需材料
{
if (RunOneTime(item.materialList[i].item))
{
}
else//条件已不足以合成物体
{
Isfinsh = true;
goto end;//跳出while循环
}
}
}
else
{
Isfinsh = true;
goto end;//跳出while循环
}
}
item.materialList[i].item.count -= item.materialList[i].count;
}
TotoalCoin -= item.costGold;
MaxCount += 1;
end:
;
}
return MaxCount;//返回可合成item最大值
}
}
public MaterialData CreatData(int materialCount, int itemCount, int id, int costGold, params MaterialData[] materialDatas)//创建单个合成规则
{
MaterialData material = new MaterialData();
material.count = materialCount;
ItemData item = new ItemData();
item.id = id;
item.count = itemCount;
item.costGold = costGold;
item.materialList = new List<MaterialData>();
if (materialDatas != null && materialDatas.Length > 0)
{
for (int i = 0; i < materialDatas.Length; i++)
{
item.materialList.Add(materialDatas[i]);
}
}
material.item = item;
return material;
}
public void CreatMater()//初始化合成规则,传入初始变量
{
materE = CreatData(1, Ecount, 5, -1, null);//不可合成装备,假设合成此物的金币为-1
materF = CreatData(5, Fcount, 6, -1, null);
materC = CreatData(1, Ccount, 3, -1, null);
materG = CreatData(9, Gcount, 7, -1, null);
materB = CreatData(3, 0, 2, 53, materE, materF);//合成所需金币53
materD = CreatData(4, 0, 4, 58, materG);//合成所需金币58
itemDataA = new ItemData();
itemDataA.costGold = 26;
itemDataA.id = 1;
itemDataA.count = 0;
itemDataA.materialList = new List<MaterialData>
{
materB,
materC,
materD
};
}
public bool RunOneTime(ItemData item)
{
bool IsEasyModle = true;
int count = item.materialList.Count;
if (count == 0)//判断装备是否可合成
{
Debug.Log("合成上一级所需子物体不可合成哦!");
return false;
}
for (int i = 0; i < item.materialList.Count; i++)//初步判断复杂度,并且根据复杂度改变算法
{
if (item.materialList[i].item.costGold > 0)//若所需子物体可合成
{
IsEasyModle = false;
}
}
if (IsEasyModle)//简易算法
{
for (int i = 0; i < item.materialList.Count; i++)
{
if (item.materialList[i].item.count < 1)
{
Debug.Log("合成物体所需材料不足");
return false;
}
else
{
item.materialList[i].item.count -= 1;//消耗一个所需材料
}
}
TotoalCoin -= item.costGold;
item.count += 1;
return true;
}
else//复杂算法
{
for (int i = 0; i < item.materialList.Count; i++)
{
if (item.materialList[i].item.count < 1)
{
if(RunOneTime(item.materialList[i].item))//判断所需材料是否可以合成
{
item.materialList[i].item.count += 1;
}
else
{
return false;
}
}
else
{
item.materialList[i].item.count -= 1;//消耗一个所需材料
}
}
item.count += 1;
TotoalCoin -= item.costGold;
if (TotoalCoin >= 0)
{
return true;
}
else
{
return false;
}
}
}
}
代码分为复杂算法与简易算法,当合成装备时,所需的子物体不可合成时,就直接运行下列代码进行运算,不跳入遍历进行运算:
for (int i = 0;i< item.materialList.Count;i++)//初步判断复杂度,并且根据复杂度改变算法
{
if (item.materialList[i].item.costGold > 0)//若所需子物体可合成
{
IsEasyModle = false;
}
}
if (IsEasyModle)//简易算法
{
int MaxCount = TotoalCoin / item.costGold;//无视基础装备数的情况下可合成的最大个数
for (int i = 0;i<item.materialList.Count;i++)
{
if(item.materialList[i].item.count/ item.materialList[i] .count < MaxCount)//若所需物体小于最大可合成数
{
MaxCount = item.materialList[i].item.count / item.materialList[i].count;
}
}
TotoalCoin -= MaxCount * item.costGold;
return MaxCount;//返回可合成item最大值
}
若所合成物体较为被俄罗斯套娃了,也就是子物体可以继续合成,就进行遍历,首先进行持有金币的判断,判断是否足够完成一次遍历,若金币充足便开始计算合成,避免造成算力浪费,算法较为暴力。
else//复杂算法
{
int MaxCount = 0;
bool Isfinsh = false;
while (!Isfinsh & TotoalCoin > item.costGold)//若总金币大于合成目前物体所需金币,开始遍历运算
{
for (int i = 0;i< item.materialList.Count;i++)
{
if (item.materialList[i].item.count < item.materialList[i].count)//若合成一次所需物体数量不足
{
if (TotoalCoin >= item.materialList[i].item.costGold*(item.materialList[i].count - item.materialList[i].item.count) + item.costGold)//剩余金币足够合成材料费用
{
int num = item.materialList[i].count - item.materialList[i].item.count;
for (int x = 0;x < num; x++)//合成X个所需材料
{
if (RunOneTime(item.materialList[i].item))
{
}
else//条件已不足以合成物体
{
Isfinsh = true;
goto end;//跳出while循环
}
}
}
else
{
Isfinsh = true;
goto end;//跳出while循环
}
}
item.materialList[i].item.count -= item.materialList[i].count;
}
TotoalCoin -= item.costGold;
MaxCount += 1;
end:
;
}
return MaxCount;//返回可合成item最大值
}
子物体缺少时会跳入子物体合成的函数中,若子物体缺少并且可合成,就再跳入合成中(有金币判断,不够钱了就停止)
public bool RunOneTime(ItemData item)
{
bool IsEasyModle = true;
int count = item.materialList.Count;
if (count == 0)//判断装备是否可合成
{
Debug.Log("合成上一级所需子物体不可合成哦!");
return false;
}
for (int i = 0; i < item.materialList.Count; i++)//初步判断复杂度,并且根据复杂度改变算法
{
if (item.materialList[i].item.costGold > 0)//若所需子物体可合成
{
IsEasyModle = false;
}
}
if (IsEasyModle)//简易算法
{
for (int i = 0; i < item.materialList.Count; i++)
{
if (item.materialList[i].item.count < 1)
{
Debug.Log("合成物体所需材料不足");
return false;
}
else
{
item.materialList[i].item.count -= 1;//消耗一个所需材料
}
}
TotoalCoin -= item.costGold;
item.count += 1;
return true;
}
else//复杂算法
{
for (int i = 0; i < item.materialList.Count; i++)
{
if (item.materialList[i].item.count < 1)
{
if(RunOneTime(item.materialList[i].item))//判断所需材料是否可以合成
{
item.materialList[i].item.count += 1;
}
else
{
return false;
}
}
else
{
item.materialList[i].item.count -= 1;//消耗一个所需材料
}
}
item.count += 1;
TotoalCoin -= item.costGold;
if (TotoalCoin >= 0)
{
return true;
}
else
{
return false;
}
}
}
需要工程的私聊我啦!