学C++4月,却做不出这个程序,郁闷!!求一例程!!!!

LeeAn 2003-08-30 10:52:36
求:
兔子,狐狸,蔬菜的过河问题!!!!(用C语言的)
请问该用什么算法:回朔,剪枝???
最好给出例程让我参考看看!!!
...全文
47 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
chenkuizhong 2003-09-17
  • 打赏
  • 举报
回复
下面完整的代码,在VC6.0中已经通过了

#include<iostream.h>

//狐狸为1,兔子为2,蔬菜为4
//这样由于狐狸和兔子不能在一起,兔子和蔬菜不能在一起
//所以河的左边和右边不能为3,也不能为6

void out(int i,int j) //此函数为输出函数,当j=0是从左边到右边,i则代表物体
{
if(j==0)
{
switch(i)
{
case 1:
cout<<"狐狸---->"<<endl; //表示狐狸从河的左边-->右边
break;
case 2:
cout<<"兔子-->"<<endl;
break;
case 4:
cout<<"蔬菜-->"<<endl;
break;
}
}
else
{
switch(i)
{
case 1:
cout<<"狐狸<---"<<endl;
break;
case 2:
cout<<"兔子<---"<<endl;
break;
case 4:
cout<<"蔬菜<---"<<endl;
break;
}
}
}

void main()
{
int l[3]={1,2,4}; //初始化河的左边
int r[3]={0,0,0}; //初始化河的右边
int i=3,j=0,sl=0,sr=0,m=0,k=0,n=0;



while(i>=0) //当河左边有物体时循环
{
sl=0; //河左边的总数
sr=0; //河右边的总数

for(m=0;m<i;m++)
{
sl=sl+l[m];

}

for(m=0;m<i;m++)//从河的左边到右边
{
if((sl-l[m])!=3&&(sl-l[m])!=6)//找出符合条件的物体
{
k=l[m];
r[j++]=k;
out(k,0);
i--;
for(n=m;n<i;n++)
{
l[n]=l[n+1];
}
break;
}

}



for(m=0;m<j;m++)
{
sr+=r[m];
}

if(sr==3||sr==6) //从河的右边到左边
{
for(m=0;m<j;m++)
{
if((sr-r[m])!=3&&(sr-r[m])!=6)
{
k=r[m];
l[i++]=k;
out(k,1);
j--;
for(n=m;n<j;n++)
{
r[n]=r[n+1];
}
break;
}
}
}

}
}
chenkuizhong 2003-08-31
  • 打赏
  • 举报
回复
#include<iostream.h>

//以下是狗、鸡、米的解答,设狗为1,鸡为2,米为3
//所以河的左边不能=3和5,河的右边也不能=3和5(因为,狗和鸡独自不能在一起,鸡和米也不能独自在一起)
void out(int i,int j)
{
if(j==0)
{
switch(i)
{
case 1:
cout<<"狗---->"<<endl;
break;
case 2:
cout<<"鸡-->"<<endl;
break;
case 4:
cout<<"米-->"<<endl;
break;
}
}
else
{
switch(i)
{
case 1:
cout<<"狗<---"<<endl;
break;
case 2:
cout<<"鸡<---"<<endl;
break;
case 4:
cout<<"米<---"<<endl;
break;
}
}
}

void main()
{
int l[3]={1,2,4},r[3];
int i=3,j=0,sl=0,sr=0,m=0,k=0,n=0;


r[0]=0;
r[1]=0;
r[2]=0;

while(i>=0)
{
sl=0;
sr=0;
for(m=0;m<i;m++)
{
sl=sl+l[m];

}

for(m=0;m<i;m++)
{
if((sl-l[m])!=3&&(sl-l[m])!=6)
{
k=l[m];
r[j++]=k;
out(k,0);

i--;
for(n=m;n<i;n++)
{
l[n]=l[n+1];
}
break;
}

}



for(m=0;m<j;m++)
{
sr+=r[m];
}
if(sr==3||sr==6)
{
for(m=0;m<j;m++)
{
if((sr-r[m])!=3&&(sr-r[m])!=6)
{
k=r[m];
l[i++]=k;
out(k,1);
j--;
for(n=m;n<j;n++)
{
r[n]=r[n+1];
}
break;
}
}
}

}
}
wuhaiwen1983 2003-08-31
  • 打赏
  • 举报
回复
很好啊!
liwei55555 2003-08-31
  • 打赏
  • 举报
回复
应该用回溯法
terryiu35 2003-08-31
  • 打赏
  • 举报
回复
各位哥哥,请指教我那里可以下载MSDN呢?

谢谢谢~~~
tiger999 2003-08-31
  • 打赏
  • 举报
回复
这种问题用状态机解很容易。
Kusk 2003-08-30
  • 打赏
  • 举报
回复
哦,还有,这些是算法问题,和C++没有关系。你就是再学上4个月C++恐怕帮助也不大啊。
Kusk 2003-08-30
  • 打赏
  • 举报
回复
典型的宽度优先搜索,你应该到数据算法版问。
bahanzo1 2003-08-30
  • 打赏
  • 举报
回复
我也不能写出这个程序:(
描述一下吧:
将狐狸,兔子,白菜表示成向量(1,1,1),而最终的状态是(0,0,0),中间不允许出现的状态
有两个:(1,1,0)和(0,1,1),小船上的状态可以表示为(a,b,c),过河为负,回来为正,即a,b,c 的取值只有1,0,-1三个,
至于用什么方法我也不清楚,你自己想想吧
Wincent 2003-08-30
  • 打赏
  • 举报
回复
不错!
Skt32 2003-08-30
  • 打赏
  • 举报
回复
//将物品带过河了。开始入right队。
//进行判断,看带来的东西是否满足题目的条件
//如果队列返回1,则表示队列已经满了,问题已经解决
printf("带%s从源岸到目的岸",tmp);

if (push_right(tmp)!=1)
{
 //没有结束,继续进行搜索
 if(ret(right[0])&ret(right[1])==0)//判断入队以后是否可以满足条件
 {
 //不满足条件,把一个物品带回到对岸了。
 move(-1);
 }
 else
 //条件满足,接着从源岸将物品带过来
 move(1);
}
else
printf("问题结束");
}
//从目的岸向源岸移动物体
else
{
while(1)
{
tmp=pop_right();//从右边的队列处取出一个物品
//看剩下的物品猎人不在的时候是否能够共存
printf("带%s从目的岸回到源岸",tmp);

if(ret(right[1])&ret(right[2])==0)
{
 //不能共存表示出队不成功,重新将物品进队,然后重新出队
 push_right(tmp);
}
else
break;//出队成功 退出循环
}
//因为不需要对源岸的队列进行判断时候为满,所以只要继续移动物品就可以了
push_left(tmp);//这里写的也比较简单了,因为总共这个是时候对岸只会有两个物品,所以就没有写判断语句,如果过和的东西要多了,就不能这样写了,需要加个判断,判断他们是否满足条件
//接着进行物品的移动
move(1);
}

}

//此函数用于确定物品的值
//狼为1,羊为0,菜为1
int ret(object)
{
 switch(object)
 {
 case yang:
  return 0;
  break ;
 case lang:
  return 1;
  break ;
 case cai:
  return 1;
  break ;
 }
}








原作者:冬虫夏草
来 源:不详
共有55位读者阅读过此文
Skt32 2003-08-30
  • 打赏
  • 举报
回复
猎人、狼、羊过河问题


www.wzdn.net 2002-3-30 网络技术

题目:假定一个人要把他带的一条狗,一只羊和一袋菜用一条小船摆渡到河的对岸。由于船很小,每次摆渡只能多带一个乘客,不能把狗和羊,羊和菜,单独留在河的同一岸。问主人怎样才能将狗,羊和菜安全运过河去?

这道题目是我帮一个朋友写的图论的作业,里面有很多错误了!大家看了多给提意见了!

解答:
//问题思路:先设定一个环行队列,每当带走一个物品的时候就把剩下的东西向前移动,当队列为零的时候,就可以说明所有的物品都已经
//运送到了对岸。在对岸利用队列可以实现这个功能,当运送过来的东西会和已经在岸边的东西发生冲突时,可以换一个物品带走。而
//不会将刚带来的东西再带回去,不会使程序产生死循环。

#include "stdio.h"

//此部分代码写的有些过于重复了,因为很长时间没有写C程序了,对于指针的有些用法给忘,所以就写了个流水帐,望见凉
char left[3],right[3];
int x;
int heard=0,tail=0;
//left数据进队
int push_left(x);
char x;
{
 tail=(tail+1)%3;
 if(tail==head)
 {
  if(tail==0) tail=2;
  else tail--;
  return 1; //进队失败,队列已经满了
 }
  left[tail]=x;
  return 0;
}
//left数据出队
int pop_left()
{
 char x;
 if(hear==tail)
  return NULL;//队列为空
 head=(head+1)%3;
 x=left[head];
 return x;
}
//right数据进队
int push_right(x)
char x;
{
 tail=(tail+1)%3;
 if(tail==head)
 {
 if(tail==0) tail=2;
 else tail--;
 return 1; //进队失败,队列已经满了
}
 left[tail]=x;
 return 0;
}
//right数据出队
int pop_left()
{
char x;
 if(hear==tail)
 return NULL;//队列为空
 head=(head+1)%3;
 x=left[head];
 return x;
}

void main()
{
//设定数组包括狼羊菜三种,初始化的值为2,如果数组的值为2则表示这个东西已经不在此处.
// man 为人,b为过桥的标志,b=1源岸--->目的岸 b=-1目的岸--->源岸
//left为源岸right为目的岸
//狼的值为1,羊的值为0,菜的值为1
//如果人不在的话,那只要两种东西的& 的值为0那他们就不能够共存!
//利用递归来进行问题的求解

//初始化队列的值,应该有很多种排列方式,由于没有时间了,所以就写了这一种了:)
 push_left(lang);
 push_left(yang);
 push_left(cai);

//开始向目的岸运送东西
 move(1);
}
void move(direct)
{
 int tmp; //交换用变量
 //从源岸向目的岸移动物体
 if(direct==1)
 {
 while(1)
 {
 tmp=pop_left();
 if(left[1]&left[2]==0)
 {
 //出队不成功,重新将物品进队,然后重新出队
 push_left(tmp)
 }
 else
 break;//出队成功 退出循环
}
Skt32 2003-08-30
  • 打赏
  • 举报
回复
http://www.hsshn.pudong-edu.sh.cn/xdyteaching/ISATTM%5Cxkrightpchs2-1-2.htm
1cs1ak1 2003-08-30
  • 打赏
  • 举报
回复



编译原理里讲过的。
同意Kusk(Kusk) ( )
这和C++没有关系。



64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧