分酒问题

最近学校弄课程设计,自己弄好后就顺便帮同学们的看了看。下面就是我对这两个问题的思路。
分酒问题
这个问题应该可以说很类似汉洛塔问题.
A容器8单位,B容器5单位,C容器3单位
初始时:A容器8单位,B、C容器0单位.
达到的效果为:得到两个4单位。
根据容器容量的限制,肯定是A和B最后得到4单位。
那么我们可以想想倒的过程应该是:
A容器倒出,B容器倒进,C容器为中介(注:这里所说的是总的过程中,当然中间过程都
有可能是倒进与倒入。
思路已经很清楚了,三个瓶倒来倒出也就是6种倒法.要么
A->B
A->C
B->C
B->A
C->A
C->B
这样应该想到用循环:
i倒入j,
for (i = 0 ; i <= 2 ; i++ )
 for (j = 0 ; j <= 2 ; j++ )
当然不能自己往自己倒,加个判断if(i!=j),然后开倒。
为了使程序模块化把"倒"这一功能设置为一函数Work(int i,int j,Content** Cur)
写到着想起来忘了写用什么存储相关数据了,在和同学交谈时发现他们在选择存储结构时不知道怎么下手
我觉得应该有两点原因:1.问题没分析清楚2.数据结构基础知识没学好。
下面接着分析:
首先问自己我们要操作什么数据和我们要什么数据?
在这里我们要操作的是三个酒瓶的容量,我们要的是倒酒过程中的顺序。
这样自然想到用数组存储三个酒瓶的容量,定义一结构体存储倒酒的过程,在此用单链表
typedef struct s{ //用单链表保存查找过程
int wine[3];//对应瓶中的酒量
struct s *Next;
}Content;
为了方便操作设置一判断三个瓶是否为满的开关:三维数组int Check[9][6][4];应该可以看出它的作用。
在此不说明了。
这样就可以顺利开写程序了:
1.初始化
void init()//完成相应初始化
{
 for(int i = 1;i <= 8; i++)
 for(int j = 1;j <= 5; j++)
 for(int k = 1;k <= 3; k++)
 Check[i][j][k] = 0;
 Check[8][0][0] = 1;
 S->wine[0] = 8;
 S->wine[1] = 0;
 S->wine[2] = 0;
 S->Next = NULL;
 Head = S;
}
2.倒酒
int Work( int i , int j , Content** Cur) //将第 i 杯中的酒倒入第 j 杯中
{

 if ( (*Cur)->wine[i] == 0 || (*Cur)->wine[j] == TOT[j] ) {//当i为空或者j为满那么就完成不了该操作
 return -1 ;
 }
 Content *Temp=new Content;//临时变量
 Temp->wine[0] = (*Cur)->wine[0];
 Temp->wine[1] = (*Cur)->wine[1];
 Temp->wine[2] = (*Cur)->wine[2];
 Temp->Next = NULL;
 if ( (*Cur)->wine[i] + (*Cur)->wine[j] > TOT[j] ) {//当i向j中加入时超过j的容器
 Temp->wine[i] = (*Cur)->wine[i] + (*Cur)->wine[j] - TOT[j] ;
 Temp->wine[j] = TOT[j];
 }
else {//当i向j中加入时不超过j的容器
 Temp->wine[j] = (*Cur)->wine[i] + (*Cur)->wine[j] ;
 Temp->wine[i] = 0 ;
 }
 if (Check[Temp->wine[0]][Temp->wine[1]][Temp->wine[2]])
 {
 delete Temp;
 return -2;
 }
 (*Cur)->Next = Temp;//保存临时变量
 if ( Done ( Temp ) )
 return 1;
 Check[Temp->wine[0]][Temp->wine[1]][Temp->wine[2]] = 1;//对应的为满
 return 2;
}
这应该是本程序和核心部分.不过也不难,且听我道来。
当i为空或者j为满那么自然就完成不了该操作。接着加入临时变量存储倒酒的过程,接着分两种问题讨论:
1.当i向j中加入时超过j的容器,
2.当i向j中加入时不超过j的容器
为了不重复操作当设置了check三维数组,当已经出现的操作就删除.接着把临时变量如存在就记录到结构体变量中。
如何达到目的就结束,否则递归重复就可以了。

posted @ 2008-09-03 23:00  小军人  阅读(1579)  评论(1编辑  收藏  举报