算法题:水杯倒水的问题

简介:

之前好像在博客园看到这样的题目:

1.有3个容器,各是20升,13升,7升, 形状不同也不透明。一开始20升的容器里面装了20升水,反正倒来倒去最后要让20升和13升容器各装了10升水


2. 2个外形不同的瓶子,各装800毫升水,另外还有1个300毫升的杯子

现在有4个人,不限制喝的次数,想办法让每个人都正好喝到400毫升水


第一第二道题目,口头说明解法就行了 
第三个题,就是从第一第二题里面随便选择一个,使用编程来求解

于是乎..觉得有趣.便做了起来...花了一个下午的时间..终于做出来了:

首先建了一个水杯类: //以下程序只是基于可运行..至于代码的可看性和性能,暂时还没做优化
   public class Cut
    {
        private int _maxValue;//杯子的最大值
        public int MaxValue
        {
            get
            {
                return _maxValue;
            }
        }
        private int _currentValue;//杯子当前值
        public int CurrentValue
        {
            get
            {
                return _currentValue;
            }
            set
            {
                _currentValue = value;
            }
        }

        public Cut(int maxValue,int currentValue)
        {
            _maxValue = maxValue;
            _currentValue = currentValue;
        }
    }
然后在控制台程序环境下:
 class Program
    {
        private static List<int[]> valueList = new List<int[]>();//用于记录正确的步骤
        private static int[] values = new int[3];//当前的步骤
        private static Cut c7 = new Cut(7, 0);
        private static Cut c13 = new Cut(13, 0);
        private static Cut c20 = new Cut(20, 20);
        static void Main(string[] args)
        {
            valueList.Clear();
            ChangeCut(ref c7, ref c13, ref c20);
        }
        static bool GetDirection(int[] currentValues)//true表示可以继续下一次[节点不存在],false则反之[表示节点存在]
        {
            if (valueList.Count == 0)//第一次时.不存在重复节点,返回真
            {
                return true;
            }
            int count = 0;
            for (int i = 0; i < valueList.Count; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (valueList[i][j] == currentValues[j])//只要发现不相等,转入下一个
                    {
                        count++;
                        if (count == 3)
                        {
                            return false;
                        }
                    }
                    else
                    {
                        count = 0;
                        break;

                    }
                }
            }
            return true;

        }
        static void ChangeCut(ref Cut c1, ref Cut c2, ref Cut c3)
        {
            Cut cutA = c2;//第一次交换的值
            Cut cutB = c3;;//第一次交换的值
            while (true)
            {
                if (!ChangeTwoCut(ref cutA, ref cutB))//交换两个杯的值
                {
                    valueList.RemoveAt(valueList.Count - 1);//交换失败时.删除最后一个节点
                    c7.CurrentValue = valueList[valueList.Count - 1][0];//退回上一节点的值
                    c13.CurrentValue = valueList[valueList.Count - 1][1];//退回上一节点的值
                    c20.CurrentValue = valueList[valueList.Count - 1][2];//退回上一节点的值

                }
                RadomCut(ref c1, ref c2, ref c3, out cutA, out cutB);//随机取两个杯交换
            }
        }
        static void RadomCut(ref Cut c1, ref Cut c2, ref Cut c3, out  Cut c11, out Cut c12)//随机产生两个杯
        {
            Random rd = new Random();
            int result = rd.Next(3);
            if (result == 0)
            {
                c11 = c1;
            }
            else if (result == 1)
            {
                c11 = c2;
            }
            else
            {
                c11 = c3;
            }
            int result2 = rd.Next(3);
            while (result2 == result)//用于产生不和上面重复的值
            {
                result2 = rd.Next(2);
            }
            if (result2 == 0)
            {
                c12 = c1;
            }
            else if (result2 == 1)
            {
                c12 = c2;
            }
            else
            {
                c12 = c3;
            }
        }
        static bool ChangeTwoCut(ref Cut c1, ref Cut c2)
        {
            bool result = false;
            int valueA;
            int valueB;
            int tempA = c1.CurrentValue;
            int tempB = c2.CurrentValue;
          //默认先走左边
            GetChangedValue(c1, c2, out valueA, out valueB, true);//两个杯交换后的值
            c1.CurrentValue = valueA;
            c2.CurrentValue = valueB;
            if (GetDirection(new int[] { c7.CurrentValue, c13.CurrentValue, c20.CurrentValue }))
            {
                result = true;
            }
            else  //走右边
            {
                GetChangedValue(c1, c2, out valueA, out valueB, false);
                c1.CurrentValue = valueA;
                c2.CurrentValue = valueB;
                if (GetDirection(new int[] { c7.CurrentValue, c13.CurrentValue, c20.CurrentValue }))
                {
                    result = true;
                }
            }
            if (result)
            {
                GetResult();
            }
            else //失败,还原值
            {
                c1.CurrentValue = tempA;
                c2.CurrentValue = tempB;
            }
            return result;
        }
        static void GetChangedValue(Cut c1, Cut c2, out int valueA, out int valueB, bool AtoB)//两种情况,一种A的值给B,一种B的值给A
        {
            int maxValue = c1.CurrentValue + c2.CurrentValue;
            //边界测定
            if (c1.CurrentValue == 0)
            {
                valueA = c2.CurrentValue > c1.MaxValue ? c1.MaxValue : maxValue;
                valueB = maxValue - valueA;
            }
            else if (c1.CurrentValue == c1.MaxValue)
            {
                int need = c2.MaxValue - c2.CurrentValue;
                if (c1.CurrentValue >= need)
                {
                    valueA = c1.CurrentValue - need;
                    valueB = c2.CurrentValue + need;
                }
                else
                {
                    valueA = 0;
                    valueB = maxValue;
                }
            }
            else if (c2.CurrentValue == 0)
            {
                valueB = c1.CurrentValue > c2.MaxValue ? c2.MaxValue : maxValue;
                valueA = maxValue - valueB;
            }
            else if (c2.CurrentValue == c2.MaxValue)
            {
                int need = c1.MaxValue - c1.CurrentValue;
                if (c2.CurrentValue > need)
                {
                    valueA = c1.CurrentValue + need;
                    valueB = c2.CurrentValue - need;
                }
                else
                {
                    valueA = maxValue;
                    valueB = 0;
                }
            }
            else //非边界值时
            {
                if (AtoB)//A的值给B时
                {
                    valueB = maxValue > c2.MaxValue ? c2.MaxValue : maxValue;
                    valueA = maxValue - valueB;
                }
                else//B的值给A时
                {
                    valueA = maxValue > c1.MaxValue ? c1.MaxValue : maxValue;
                    valueB = maxValue - valueA;
                }
            }
        }

        static void GetResult() //添加正确步骤或显示结果
        {
            if (c20.CurrentValue == 10 || c13.CurrentValue == 10)
            {
                int[] newValue = new int[3] { c7.CurrentValue, c13.CurrentValue, c20.CurrentValue };
                valueList.Add(newValue);
                Console.WriteLine("结果已出如下:");
                for (int i = 0; i < valueList.Count; i++)
                {
                    Console.WriteLine("第" + i.ToString() + "步: " + valueList[i][0].ToString() + ":" + valueList[i][1].ToString() + ":" + valueList[i][2].ToString());
                }
                Console.ReadLine();
            }
            else
            {
                int[] newValue = new int[3] { c7.CurrentValue, c13.CurrentValue, c20.CurrentValue };
                valueList.Add(newValue);
                Console.WriteLine(newValue[0].ToString() + ":" + newValue[1].ToString() + ":" + newValue[2].ToString());
            }
        }
    }


相关文章
|
2月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
268 0
|
2月前
|
数据采集 分布式计算 并行计算
mRMR算法实现特征选择-MATLAB
mRMR算法实现特征选择-MATLAB
204 2
|
3月前
|
传感器 机器学习/深度学习 编解码
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
226 3
|
3月前
|
存储 编解码 算法
【多光谱滤波器阵列设计的最优球体填充】使用MSFA设计方法进行各种重建算法时,图像质量可以提高至多2 dB,并在光谱相似性方面实现了显著提升(Matlab代码实现)
【多光谱滤波器阵列设计的最优球体填充】使用MSFA设计方法进行各种重建算法时,图像质量可以提高至多2 dB,并在光谱相似性方面实现了显著提升(Matlab代码实现)
163 6
|
2月前
|
机器学习/深度学习 算法 机器人
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
178 8
|
2月前
|
机器学习/深度学习 算法 自动驾驶
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
基于导向滤波的暗通道去雾算法在灰度与彩色图像可见度复原中的研究(Matlab代码实现)
188 8
|
2月前
|
机器学习/深度学习 算法 数据可视化
基于MVO多元宇宙优化的DBSCAN聚类算法matlab仿真
本程序基于MATLAB实现MVO优化的DBSCAN聚类算法,通过多元宇宙优化自动搜索最优参数Eps与MinPts,提升聚类精度。对比传统DBSCAN,MVO-DBSCAN有效克服参数依赖问题,适应复杂数据分布,增强鲁棒性,适用于非均匀密度数据集的高效聚类分析。
|
3月前
|
机器学习/深度学习 传感器 算法
【高创新】基于优化的自适应差分导纳算法的改进最大功率点跟踪研究(Matlab代码实现)
【高创新】基于优化的自适应差分导纳算法的改进最大功率点跟踪研究(Matlab代码实现)
267 14

热门文章

最新文章