您的位置:首页 > 编程语言 > C语言/C++

野人和传教士过河问题的C语言源代码

2012-08-08 12:54 127 查看
2008-11-14 17:40
问题:有3个传教士和3个野人要过河,只有一艘船,这艘船每次只能载2个人过河,且无论哪边野人的数量大于传教士的数量时,野人就会吃掉传教士。怎样让他们都安全过河?

C语言源代码:

#include <stdio.h>

#include <string.h>

#define STEP_MAX 20 //来回过河的次数

#define KIND_NUM 3 //每个种类的数量

#define BOAT_NUM 2 //船的载重量

typedef enum

{

BOAT_THIS,//船在本岸

BOAT_THAT,//船在对岸

} boat_t;

typedef enum

{

ROAD_GO,//过河

ROAD_COME,//回来

} road_t;

typedef struct

{

int ye;//对岸野人数量

int man;//对岸传教士数量

boat_t boat;//船是否在对岸

} state_t;//一种局面

typedef struct

{

int ye;//野人过河数量

int man;//传教士过河的数量

road_t road;//回来或过河

} step_t;//一个步骤

state_t states[STEP_MAX]={0};

step_t steps[STEP_MAX]={0};

//判断所有的野人和传教士是否都到了对岸

bool final(state_t s)

{

const state_t cs=

{

KIND_NUM,

KIND_NUM,

BOAT_THAT

};

if(memcmp(&cs,&s,sizeof(state_t))==0)

{

return true;

}

return false;

}

//是否会发生野人杀传教士

bool bad(state_t s)

{

if(((KIND_NUM-s.ye)>(KIND_NUM-s.man) && (KIND_NUM-s.man)>0)

||(s.ye>s.man && s.man>0))

{

return true;

}

return false;

}

//第n种局面是否跟前面的相重复

bool repeat(state_t s[],int n)

{

int i;

for (i = 0; i < n; i++)

{//已经有这种情况了

if (memcmp(&states[i], &states
, sizeof(states[i])) == 0)

{

return true;

}

}

return false;

}

void output(step_t steps[STEP_MAX],int n)

{

char *kinds[KIND_NUM]={"野人","传教士"};

char *routine[2]={"过河.","回来."};

int i;

for (i = 0; i < n; i++)

{

if((steps[i].ye * steps[i].man)>0)

{

printf("%d个%s和%d个%s%s\n",steps[i].ye,kinds[0],

steps[i].man,kinds[1],routine[steps[i].road]);

}

else if(steps[i].ye>0)

{

printf("%d个%s%s\n",steps[i].ye,kinds[0],

routine[steps[i].road]);

}

else if(steps[i].man>0)

{

printf("%d个%s%s\n",steps[i].man,kinds[1],

routine[steps[i].road]);

}

}

printf("\n");

}

//搜索过河方案(n表示过河次数)

void search(int n)

{

int i,j;

if(n>STEP_MAX)

{//步数限制太少了

printf("Step Overflow!");

return;

}

if(final(states
))

{//都到对岸了

output(steps,n);

return;

}

if(bad(states
))

{//发生了野人杀传教士了

return;

}

if(repeat(states,n))

{//与前面的局面相重复了

return;

}

if(states
.boat==BOAT_THIS)

{//船在本岸

for (i = 0; i <= BOAT_NUM && i<=(KIND_NUM-states
.ye); i++)

for (j = 0; j <= BOAT_NUM-i && j<=(KIND_NUM-states
.man); j++)

{

if(i==0 &&j==0)

{

continue;

}

steps
.ye=i;

steps
.man=j;

steps
.road=ROAD_GO;

memcpy(&states[n+1], &states
, sizeof(state_t));

states[n+1].ye+=i;

states[n+1].man+=j;

states[n+1].boat=BOAT_THAT;

search(n+1);

}

}

else

{

for (i = 0; i <= BOAT_NUM && i<=states
.ye; i++)

for (j = 0; j <= BOAT_NUM-i && j<=states
.man; j++)

{

if(i==0 &&j==0)

{

continue;

}

steps
.ye=i;

steps
.man=j;

steps
.road=ROAD_COME;

memcpy(&states[n+1], &states
, sizeof(state_t));

states[n+1].ye-=i;

states[n+1].man-=j;

states[n+1].boat=BOAT_THIS;

search(n+1);

}

}

}

int main()

{

search(0);

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: