上面还有考察是不是变态的题目,我晕,扯远了,就第二题,2 明和小华买了10斤蜂蜜,装在一个大瓶子里.要把蜂蜜平分,只有两个空瓶子,一个正好装7斤,另一个正好装3斤. 怎样才能用最简单的方法把蜂蜜分出来.(上面的最简单对于电脑有点难了,只是考虑分出来,大家这个其实也是可以考虑的)
这种题目好像现在很流行,变体不少,比如,一个桶7,一个桶什么的,反正差不多吧.本来没什么,只是想看能不能用程序来完成,就用电脑来完成一下人脑基本想法,本身还是比较傻.最主要是我学习不久,什么东东都没有深入,就怕自己的代码方式,风格,思想有什么问题.希望有老手能指点我们这些小白.谢谢.
首先定义一个瓶吧,上面本来是有三个瓶,大的,小的,中的,本想是一个接口,后来还是没搞那么麻烦,只是演示,就定义一个瓶的类(Bottle),有四个属性,分别是实体名(Name),容量(Capacity),占用容量(Occupy),没占用的容量(OnOccupy). 二个字段,容量(capactity),占用容量(occupy). 一个方法倒出(Poured).一个静态方法(RandomPoured).
思路如下.把蜂蜜分出来,大至是通过不断的把瓶子里的东东倒出.这个有二种情况.
1.如7升的满的倒给10升的空瓶.这样属于
倒出的占用容量比倒进的瓶的没占用的容量小.那么倒出的会占用容量变成0.倒进的加上倒出的占用容量.
那么结果就是7的空,10升的有了7升.
2.如7升瓶满的倒给10升瓶已经有7长虹的.这样属于
倒出的占用容量比倒进的瓶的没占用的容量大.那么倒进的会变满,而倒出的会减少倒进的瓶的原没占用容量.
那么结果就是10升的满,7升的还有4升.
然后电脑就是不断组合(这是我的问题.深入的话详细让他合理对比倒出可能花费时间很多), 考虑结果就是有一个瓶有5升的OK了(本身最终是要二个瓶要5 升).
上面的静态方法就是给出二个生成的随机数(我感觉这步很不好,可惜我找不到解决方法).根据随机数分别生成一个倒出的,一个倒进的.如下代码所示.
Code
public class Bottle
{
private int capactity = 0;
private int occupy = 0;
public string Name { get; set; }
public int Capacity
{
get
{
return capactity;
}
set
{
capactity = value;
}
}
public int Occupy
{
get
{
if (occupy > capactity && occupy < 0)
throw new Exception();
return occupy;
}
set
{
if (occupy > capactity && occupy < 0)
throw new Exception();
occupy = value;
}
}
public int OnOccupy
{
get
{
return capactity - occupy;
}
}
public bool Poured(Bottle bottle)
{
if (occupy == 0 || bottle.OnOccupy == 0)
return false;
try
{
//另一个瓶的可用空间比自己的占用空间大
if (bottle.OnOccupy >= this.Occupy)
{
bottle.Occupy += this.Occupy;
this.Occupy = 0;
return true;
}
//另一个瓶的可用空间比自己占用空间小
else
{
this.Occupy -= bottle.OnOccupy;
bottle.Occupy += bottle.OnOccupy;
return true;
}
}
catch
{
return false;
}
}
public static bool RandomPoured(Random om,ref int i,ref int j)
{
i = om.Next(1, 4);
j = om.Next(1, 4);
if (i == j)
return false;
return true;
}
}
以上就是瓶子的行为了.下一步定义操作者,就是一个Main(鄙视我吧).
Code
1static void Text2()
2 {
3 Bottle big = new Bottle();
4 big.Name = "大瓶";
5 big.Capacity = 10;
6 big.Occupy = 10;
7
8 Bottle small = new Bottle();
9 small.Name = "小瓶";
10 small.Capacity = 3;
11 small.Occupy = 0;
12
13 Bottle common = new Bottle();
14 common.Name = "中瓶";
15 common.Capacity = 7;
16 common.Occupy = 0;
17
18 Random om = new Random();
19 int j = 0;
20 Console.WriteLine("---action---- 大瓶值, 中瓶值, 小瓶值.");
21 DateTime time = DateTime.Now;
22 Hashtable table = new Hashtable();
23 table.Add(" 大瓶:10, 中瓶: 0, 小瓶: 0.", "初始状态");
24 while (true)
25 {
26 int n = 0; int m = 0;
27 if (!Bottle.RandomPoured(om, ref n, ref m))
28 continue;
29 Bottle b1 = ReBottle(n, big, small, common);
30 Bottle b2 = ReBottle(m, big, small, common);
31 if(!b1.Poured(b2))
32 continue;
33
34 //string key = string.Format(" 大瓶:{0,2}, 中瓶:{1,2}, 小瓶:{2,2}.",big.Occupy, common.Occupy, small.Occupy);
35 //string value = string.Format("{0}倒给{1},", b1.Name, b2.Name);
36 //try
37 //{
38 // table.Add(key, value);
39 //}
40 //catch
41 //{
42 //}
43 string action = string.Format("{0}倒给{1}, 大瓶:{2,2}, 中瓶:{3,2}, 小瓶:{4,2}.", b1.Name, b2.Name, big.Occupy, common.Occupy, small.Occupy);
44 Console.WriteLine(action);
45 if (big.Occupy == 5 || common.Occupy == 5)
46 {
47 TimeSpan spen = DateTime.Now - time;
48 Console.WriteLine("OK!!!共用 {0} 次,共用{1}秒",j,spen);
49 break;
50 }
51 j++;
52 }
53 //foreach (DictionaryEntry s in table)
54 //{
55 // Console.WriteLine("{0}{1}",s.Value,s.Key);
56 //}
57 Console.Read();
58 }
Code
1static void Main(string[] args)
2 {
3 Text2();
4 }
5static Bottle ReBottle(int n, Bottle big, Bottle small, Bottle common)
6 {
7 if (n == 1)
8 return big;
9 else if (n == 2)
10 return small;
11 else
12 return common;
13 }
这里他就会乱倒进倒出了,至到结果.中间我想得到他的有效比较步骤(就是那些被//的代码)不过实验不成立.看下结果吧
可以看到,最后5步有点价值,可供参考.上面可以当做是一个人乱想的次数.
最后感想.电脑能做的全是靠人,我让他乱比较.他就乱比较.如果我把比较的思路给他清晰详细的.那他也会给你清晰的思考.
PS:本人水平有限(小学生可能还不如).希望能得到各位大牛的各方面指导性建议.再次谢谢.