上面还有考察是不是变态的题目,我晕,扯远了,就第二题,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
1
static 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
1
static void Main(string[] args)
2
{
3
Text2();
4
}
5
static 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:本人水平有限(小学生可能还不如).希望能得到各位大牛的各方面指导性建议.再次谢谢.