zoukankan      html  css  js  c++  java
  • 算法题:水杯倒水的问题

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

    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());
                }
            }
        }

    版权声明:本文原创发表于 博客园,作者为 路过秋天 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
    个人微信公众号
    创业QQ群:617713515
    Donation(扫码支持作者):支付宝:
    Donation(扫码支持作者):微信:
  • 相关阅读:
    Android 自动化测试 Emmagee
    接口测试
    office2010
    MonkeyRecorder
    反编译android的apk
    基于标准库的string类实现简单的字符串替换
    C++中如何在顺序容器中删除符合特定条件的元素
    结合示例说明C++中const和指针结合时怎么理解
    C++中const使用注意要点(二)
    C++中const使用注意要点(一)
  • 原文地址:https://www.cnblogs.com/cyq1162/p/846552.html
Copyright © 2011-2022 走看看