acm 人鸡米狗过河的实现

今天上网看到一到题,是关于人 鸡米狗过河的问题。借助于图的深层递归,输出所有的答案。

看了半天终于弄懂了,一下是我的理解。代码来源:http://dfpxing.i.sohu.com/blog/view/50626999.htm

 

一个人带着米,鸡,狗过河,人只能一次带一动物过河,但是鸡和狗,米和鸡不能单独呆在一起。为了安全起见,怎样过河

 理解: 设here[4](表示4个对象是否在此岸)为岸边,there[4]为对岸.每次here->there,都会有人带一动物.每次there->here 可能是只有人,或者人带一动物.每次结果都是连续的 一次go,下来是back然后再是go,back..........顺序不能乱

(1):初始化:  here[4]={0,1,1,1},there[4]={1,0,0,0};

  (2)go 去对岸的时候,从here中找出一个动物和人一起去对岸,检测here中剩余的有没有不能存在的状态(例如 米和鸡,狗和鸡),若here 岸没有一个动物了则表明成功。如不是,则继续找,如找到,转向3;

(3)back 岸边的时候,从there中找出一人或动物,改变状态之后,查看there状态是否可行,如不能存在则继续找,状态安全的话,则经行(2);

一下是代码:

#include <iostream>
#define MAXACTION  20
#define man 0//放在第一位
#define  dog  3
#define chicken  2
#define  rice   1
using namespace std;

int here [4]={0,1,1,1};
int there[4]={1,0,0,0};//状态
void  go_action(int last);
void back_action(int last);
void print();//打印结果

int action[MAXACTION];
int  step=0;


int main()
{

  go_action(man);
  return 0;
}


void go_action(int last)
{
 if(step>=MAXACTION) return ;
   for(int i=0;i<4;i++)
   {
    if(here[i]&&i!=last)//last表明是刚回岸边,不可能在返回
    {

    action[step++]=i;
    here[i]=0;
    there[i]=1;


    if(there[dog]&&there[chicken]&&there[rice])
    print();
       if(!((here[chicken]&&here[rice])||(here[chicken]&&here[dog])))  //每次都是是人带物过河,所以判断的是here岸边改变的状态可行
                      back_action(i);
        
     there[i]=0;
     here[i]=1;
     step--;
  
   
   
    }//# end if
   }//#end for


}

 

void back_action(int last)
{
 if(step>=MAXACTION) return ;
  for(int i=0;i<4;i++)
  {
     if(there[i]&&i!=last)
  {
   action[step++]=i;
   if(i!=man)
   {
   there[i]=0;
   here[i]=1;

   }
   if(!((there[dog]&&there[chicken])||(there[chicken]&&there[rice])))
                 go_action(i);
 
  there[i]=1;
  here[i]=0;
  step--;
  }//#end if
 
 
  }//#end for

 

}
void print()
{
 for(int i=0;i<step;i++)
 {
      if(i%2)
    cout<<"back: ";
   else
    cout<<"\ngo :";

   switch(action[i]){
   case man:        cout<<"    人    ";break;
   case dog:        cout<<"人  和  狗"; break;
   case chicken:    cout<<"人  和  鸡";break;
   case rice:       cout<<"人  和  米"; break;
   }
   cout<<"\t";
 }//#end for

 cout<<endl<<endl;
 
}

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值