本课题要求出完整程序,能够解决下面的问题:
一个农夫带着一只羊,一条狼和一颗白菜想从河的东岸到西岸去。河上仅有一条船。假设他每次只能带一只羊,或者一条狼,或者一颗白菜过河,并且当人不在场时,狼和羊,或羊和白菜不能单独在一起。求出他带一只羊,一条狼和一颗白菜过河的所有办法。狼和羊、羊和白菜不能单独在一起,涉及对象较多,而且运算步骤方法较为复杂,要用程序语言实现,需要将具体实例数字化。针对实现整个过程需要多步,不同步骤中各个事物所处位置不同的情况,没有对先后顺序进行约束,这就需要给各个事物依次进行编号,然后依次试探,若试探成功,进行下一步试探。这就需要使用循环或者递归算法,避免随机盲目运算且保证每种情况均试探到。
#include <stdio.h>
struct Condition { 定义结构体数组
int farmer;
int wolf;
int sheep;
int cabbage;
};
struct Condition conditions[100];
char* action[100]; 定义一个记录过程的数组
void takeWolfOver(int i) 带狼过河
{
action[i] = "带狼过河";
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] = "带狼回来";
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] = "带羊过河";
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] = "带羊回来";
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] = "带白菜过河";
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] = "带白菜回来";
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] = "独自过河";
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] = "独自回来";
conditions[i + 1].wolf = conditions[i].wolf;
conditions[i + 1].sheep = conditions[i].sheep;
conditions[i + 1].cabbage = conditions[i].cabbage;
}
void showSolution(int i) 显示解决方案
{
int c;
printf("%s\n", "Solution:");
for (c = 0; c<i; c++)
{
printf("%d. %s\n", c + 1, action[c]);
}
printf("%s\n", "Ok! Nice job!");
}
void tryOneStep(int i)
{
int c;
int j;
//check for recursion problem.
if (i >= 100) 当过程超过100步,报错
{
printf("%s\n", "Index reached 100. Something is wrong. ");
return;
}
//check for win.
if (conditions[i].farmer == 1 && 当狼,农夫,羊,白菜同时在对岸,完成
conditions[i].wolf == 1 &&
conditions[i].sheep == 1 &&
conditions[i].cabbage == 1)
{
showSolution(i);
return;
}
//check for lose.
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;
//use recursion to find out how to.
tryOneStep(0);
}