KiMoGiGi 技术文集

不在乎选择什么,而在乎坚持多久……

IT博客 首页 联系 聚合 管理
  185 Posts :: 14 Stories :: 48 Comments :: 0 Trackbacks
两个小孩去打油,一人带了一个一斤的空瓶,另一个带了一个七两和一个三两的空瓶。原计划各打一斤油,可是由于所带的钱不够,只好合打了一斤油,在回家的路上,二人想平分这一斤油,可是又没有其它工具。现只用这三个瓶子(一斤、七两、三两)精确地分出两个半斤油来。


    /*
     *  两个小孩去打油,一人带了一个一斤的空瓶,另一个带了一个七两和一个三两的空瓶。
     *  原计划各打一斤油,可是由于所带的钱不够,只好合打了一斤油,在回家的路上,二人想平分这一斤油,可是又没有其它工具。
     *  现只用这三个瓶子(一斤、七两、三两)精确地分出两个半斤油来
     *  (1斤 = 10两)
    
*/
    
public class SpearateOil
    {
        
/// <summary>
        
/// 设置每个瓶子最大容量
        
/// </summary>
        static int[] MaxOil = { 1073 };
        
/// <summary>
        
/// 存放每个瓶子历史容量
        
/// </summary>
        static List<int[]> History = new List<int[]>() { new int[] { 1000 } };
        
/// <summary>
        
/// 存放每个历史步骤
        
/// </summary>
        
/// <remarks>仅供查看</remarks>
        static List<int[]> Steps = new List<int[]>();

        
/// <summary>
        
/// 运行
        
/// </summary>
        public static void Go()
        {
            
//初始化油的容量
            int[] initialOil = { 1000 };
            
//用于记录上一步骤
            int[] lastStep = null;
            
//循环“倒油”,直到出现平均为止
            while (!(initialOil[0== 5 && initialOil[1== 5))
            {
                lastStep 
= Step(ref initialOil, lastStep);
                
//防止死循环
                if (lastStep ==null)
                {
                    
break;
                }
            }

            
//显示结果
            for (int i = 0; i < History.Count; i++)
            {
                var item 
= History[i];
                
                
if(i > 0)
                {
                    Console.WriteLine(
"{3}   {0},{1},{2}", item[0], item[1], item[2]
                        , Steps[i 
- 1][0+ "->" + Steps[i - 1][1]);
                }                
            }

        }

        
/// <summary>
        
/// “倒油 ”
        
/// </summary>
        
/// <param name="fromIndex">源油瓶索引</param>
        
/// <param name="toIndex">目标油瓶索引</param>
        
/// <param name="oilStatus">油状态</param>
        public static void SwichOil(int fromIndex, int toIndex, ref int[] oilStatus)
        {
            
int toMax = MaxOil[toIndex] - oilStatus[toIndex];
            
int from = oilStatus[fromIndex];

            
if (from >= toMax)
            {
                oilStatus[fromIndex] 
= oilStatus[fromIndex] - toMax;
                oilStatus[toIndex] 
= MaxOil[toIndex];
            }
            
else
            {
                oilStatus[toIndex] 
+= oilStatus[fromIndex];
                oilStatus[fromIndex] 
= 0;
            }
        }       

        
/// <summary>
        
/// 对比两个油的状态是否一样
        
/// </summary>
        
/// <param name="oil1"></param>
        
/// <param name="oil2"></param>
        
/// <returns></returns>
        private static bool Compare(int[] oil1, int[] oil2)
        {
            
for (int i = 0; i < 3; i++)
            {
                
if(oil1[i] != oil2[i])
                {
                    
return false;
                }
            }
            
return true;
        }

        
/// <summary>
        
/// 倒油步骤
        
/// </summary>
        
/// <param name="oil">倒油前的油瓶状态</param>
        
/// <param name="lastStep">上一个步骤</param>
        
/// <returns>返回新的步骤</returns>
        public static int[] Step(ref int[] oil, int[] lastStep)
        {
            
//新步骤
            int[] step = null;
            
//把油瓶状态做一个备份
            int[] recordOil = new int[3];
            oil.CopyTo(recordOil, 
0);

            
//循环源油瓶索引
            for (int from = 0; from < 3; from++)
            {                
                
if (oil[from] == 0)
                {
                    
//如果源油瓶为0,则continue
                    continue;
                }

                
//循环目标油瓶索引
                for (int to = 0; to < 3; to++)
                {
                    
//是否找到步骤
                    bool isFindStep = true;

                    
if (from == to)
                    {
                        
//源与目标相同的话,略过
                        continue;
                    }
                    
if (lastStep != null && lastStep[1== from && lastStep[0== to)
                    {
                        
//步骤与上一次步骤lastStep是反操作的,略过
                        continue;
                    }
                    
if (oil[to] == MaxOil[to])
                    {
                        
//目标油瓶容量已达到极限,掠过
                        continue;
                    }

                    
//“倒油”
                    SwichOil(from, to, ref oil);

                    
//查看新状态是否存在历史存在过
                    foreach (var item in History)
                    {
                        
if (Compare(item, oil))
                        {
                            
//如果有,则跳出并复原
                            isFindStep = false;
                            recordOil.CopyTo(oil, 
0);//复原
                            break;
                        }
                    }

                    
//如果已找寻到步骤
                    if (isFindStep)
                    {
                        
//记录步骤,以及记录新油瓶容量状态
                        step = new int[] { from, to };
                        
int[] newOil = new int[3];
                        oil.CopyTo(newOil, 
0);
                        History.Add(newOil);
                        
break;
                    }
                }

                
//如果找寻到步骤,就跳出循环
                if (step != null)
                {
                    Steps.Add(step);
                    
break;
                }
            }

            
return step;
        }
    }

输出结果:

0->1   3,7,0
0->2   0,7,3
1->0   7,0,3
2->1   7,3,0
0->2   4,3,3
2->1   4,6,0
0->2   1,6,3
2->1   1,7,2
1->0   8,0,2
2->1   8,2,0
0->2   5,2,3
2->1   5,5,0
posted on 2009-01-05 17:11 KiMoGiGi 阅读(686) 评论(0)  编辑 收藏 引用 所属分类: Basic
只有注册用户登录后才能发表评论。