金币合成装备算法题

下图是一个装备系统的合成图谱,箭头指向的是合成之后的装备,每合成一个装备需要消耗一些金币(标注在矩形框里面),箭头上的数字表示合成所需的材料数量。比如,要合成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;
            }
     
        }
    }

需要工程的私聊我啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值