今天上网看到一到题,是关于人 鸡米狗过河的问题。借助于图的深层递归,输出所有的答案。
看了半天终于弄懂了,一下是我的理解。代码来源: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;
}