#include <iostream>
using namespace std;
struct Condition
{
int farmer;
int wolf;
int sheep;
int cabbage;
};
//定义状态数组
Condition conditions[100];
char* action[100];
//产生某个动作之后在状态更新
void takeWolfOver(int i)
{
action[i]="take wolf over.";
conditions[i+1].wolf=1;
conditions[i+1].sheep=conditions[i].sheep;
conditions[i+1].cabbage=conditions[i].cabbage;
}
void takeWolfBack(int i)
{
action[i]="take wolf back.";
conditions[i+1].wolf=0;
conditions[i+1].sheep=conditions[i].sheep;
conditions[i+1].cabbage=conditions[i].cabbage;
}
void takeSheepOver(int i)
{
action[i]="take sheep over.";
conditions[i+1].wolf=conditions[i].wolf;
conditions[i+1].sheep=1;
conditions[i+1].cabbage=conditions[i].cabbage;
}
void takeSheepBack(int i)
{
action[i]="take sheep back.";
conditions[i+1].wolf=conditions[i].wolf;
conditions[i+1].sheep=0;
conditions[i+1].cabbage=conditions[i].cabbage;
}
void takeCabbageOver(int i)
{
action[i]="take cabbage over.";
conditions[i+1].wolf=conditions[i].wolf;
conditions[i+1].sheep=conditions[i].sheep;
conditions[i+1].cabbage=1;
}
void takeCabbageBack(int i)
{
action[i]="take cabbage back.";
conditions[i+1].wolf=conditions[i].wolf;
conditions[i+1].sheep=conditions[i].sheep;
conditions[i+1].cabbage=0;
}
//农夫单独来回
void getOverBarely(int i)
{
action[i]="get over barely.";
conditions[i+1].wolf=conditions[i].wolf;
conditions[i+1].sheep=conditions[i].sheep;
conditions[i+1].cabbage=conditions[i].cabbage;
}
void getBackBarely(int i)
{
action[i]="get back barely.";
conditions[i+1].wolf=conditions[i].wolf;
conditions[i+1].sheep=conditions[i].sheep;
conditions[i+1].cabbage=conditions[i].cabbage;
}
void showResult(int i)
{
int c;
for(c=0;c<i;c++)
{
cout<<c+1<<"."<<action[c]<<endl;
}
cout<<"Nice job!"<<endl;
}
void tryOneStep(int i)
{
int c,j;
//到达成功状态
if(conditions[i].farmer==1&&
conditions[i].wolf==1&&
conditions[i].sheep==1&&
conditions[i].cabbage==1)
{
showResult(i);
return;
}
//到达非法状态
if(conditions[i].farmer!=conditions[i].wolf&&conditions[i].wolf==conditions[i].sheep||
conditions[i].farmer!=conditions[i].sheep&&conditions[i].sheep==conditions[i].cabbage)
{
return;
}
//判断是否有重复状态
for(c=0;c<i;c++)
{
if(conditions[c].farmer==conditions[i].farmer&&
conditions[c].wolf==conditions[i].wolf&&
conditions[c].sheep==conditions[i].sheep&&
conditions[c].cabbage==conditions[i].cabbage)
{
return;
}
}
j=i+1;
if(conditions[i].farmer==0)
{
conditions[j].farmer=1;
getOverBarely(i);
tryOneStep(j);
if(conditions[i].wolf==0)
{
takeWolfOver(i);
tryOneStep(j);
}
if(conditions[i].sheep==0)
{
takeSheepOver(i);
tryOneStep(j);
}
if(conditions[i].cabbage==0)
{
takeCabbageOver(i);
tryOneStep(j);
}
}else
{
conditions[j].farmer=0;
getBackBarely(i);
tryOneStep(j);
if(conditions[i].wolf==1)
{
takeWolfBack(i);
tryOneStep(j);
}
if(conditions[i].sheep==1)
{
takeSheepBack(i);
tryOneStep(j);
}
if(conditions[i].cabbage==1)
{
takeCabbageBack(i);
tryOneStep(j);
}
}
}
int main()
{
conditions[0].farmer=0;
conditions[0].wolf=0;
conditions[0].sheep=0;
conditions[0].cabbage=0;
tryOneStep(0);
getchar();
return 0;
}
1. 过程回溯法。把人、狼、羊、白菜看成A、B、C、D。过河的时候从ABCD中选两个过河,在 * 选一个回来。若发生狼跟羊、羊跟白菜在同一个岸边,且农夫不在场,则回溯. * * 2. 图的遍历。设从南岸到北岸,在南岸ABCD的各个状态是(用二进制表示):0000,在 * 北岸的时候各个状态是:1111。所以过河问题就是从0000起始状态到1111最终状态的 * 过程。易得,总共有16中状态。然后把每一种状态看成图的一个结点,把可以连通的 * 结点用有向边连起来,就构成的一个有向图。从0000这个结点遍历(深度优先或者广 * 度优先)图,遍历到1111结点则找到解。 * * 3. 状态回溯法。设从南岸到北岸,在南岸ABCD的各个状态是(用二进制表示):0000,在 * 北岸的时候各个状态是:1111。所以过河问题就是从0000起始状态到1111最终状态的 * 过程。易得,总共有16中状态。从第一种状态0000开始搜索,搜索当前状态下可以到达的 * 状态,搜索到一个则把这个状态看成当前状态,继续搜索。若出现当前状态搜索无可到达 * 的状态或已遍历所有搜索出来的状态,则回溯。直到到达1111状态。 * * 4. 状态队列搜索法。跟思路3类似,只是搜索的方式不一样。思路3中用栈的思想进行深度搜索 * 这里采用队列的思想进行广度搜索。