共有回帖数 0 个
-
法国数学家Poisson在青年时代研究过一个有趣的数学问题:某人有12品脱的啤酒一瓶,想从中倒出6品脱,但他也没有6品脱的容器,仅有一个8品脱和5品脱的容器,怎样倒才能将啤酒分为两个6品脱呢?建个数学模型,编个程序求一下倒酒的过程!
我这有一个,大家看一下:
/*有四个人喝酒,有两个八两装满酒的瓶,
只有一个三两的杯子。他们要平分这些酒,
但是不能借用其它的工具,你觉得应该怎么做?
*/
#includeiostream.h
int position[6354][8];//状态集
long ptop=0;
//后来实验的结果是,在求解的过程中可能出现6354种状态
int object[7]={8,8,0,0,0,0,0};//0,1瓶,2杯,3~6人,写在一起只是为了便于搜索
int solution[60][3];//保存解过程:a,b,n a-b(n)
int cmin=100;//最少步数
int scount=0;
int pour(int a,int b)
//从a编号对象往b编号对象转移时,反回可行转移的酒量,返回0表示非法
{
int empty;
if(object[a]==0)return 0;
if(a==b)return 0;
//if(a2)return 0;//不能从人往容器转移
if(b3)//容器往容器
{
empty=b2?8-object:3-object;
if(object[a]empty)return object[a];
return empty;
}
else//容器往人
{
empty=4-object;
if(object[a]empty)return 0;
return object[a];
}
}
inline void move(int a,int b,int n)//转移
{
object[a]-=n;
object+=n;
}
bool oldposition(int c)//判断是否是曾经出现过的状态
{
int i,j;
for(i=0;iptop;++i)
{
for(j=0;j7;++j)
if(object[j]!=position[j])
break;
if(j==7)
{
if(cposition[7])
{
position[7]=c;
return false;
}
else
return true;
}
}
for(i=0;i7;++i)
position[ptop]=object;
position[ptop][7]=c;
++ptop;
return false;
}
void resolve(int c)
{
if(object[0]==0&&object[1]==0&&object[2]==0)
//得到一个解,输出
{
if(ccmin)cmin=c;
cout"第"(++scount)"个解,共"c"步实现:"endl;
for(int i=0;ic;++i)
coutsolution[0]"-"solution[1]":"solution[2]endl;
cout"-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+"endl;
return;
}
if(oldposition©)return;//好汉不走回头路
int a,b,n;
for(a=0;a3;++a)
for(b=0;b7;++b)
if((n=pour(a,b))0)
{
solution[c][0]=a;
solution[c][1]=b;
solution[c][2]=n;
move(a,b,n);
resolve(c+1);//下一步搜索
move(b,a,n);
}
}
void main()
{
resolve(0);
cout"完成需要的最少步数是:"cminendl;
}
值得解释一下的,程序中object[0]和[1]是两瓶酒,object[2]是那个杯子,object[3]到[6]是那四个人的肚子,程序没什么新鲜玩艺简单的搜索。
运行时间比较长,输出结果用重定向到文件:cpp1solution.txt
拿出其中一种解:
第816个解,共24步实现:
start: 8800000
0-2:3 5830000
2-4:3 5800300
0-2:3 2830300
0-5:2 0830320
2-0:3 3800320
1-2:3 3530320
2-0:3 6500320
1-2:3 6230320
2-0:2 8210320
2-4:1 8200420
0-2:3 5230420
1-0:2 7030420
2-1:3 7300420
0-2:3 4330420
2-1:3 4600420
0-2:3 1630420
2-1:2 1810420
2-6:1 1800421
1-2:3 1530421
2-0:3 4500421
1-2:3 4230421
1-5:2 4030441
2-6:3 4000444
0-3:4 0004444
楼主 2016-03-09 12:34 回复
Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
意见反馈 |
关于直线 |
版权声明 |
会员须知