C语言编程!!!羊,狼,白菜,过河方法~!
一个人带着一只羊,一条狼和一个白菜想过河,假设他每次只能带一只羊,或者一条狼,或者一棵白菜过河,并限定人不在场时,狼和羊,或羊和白菜不能单独在一起,试编写程序求出他带一只羊,一条狼,一个白菜过河的方法.
答案是;#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STEP 20
//index: 0 - 狼,1-羊,2-菜,3-农夫,value:0-本岸,1-对岸
int a[MAX_STEP][4];
int b[MAX_STEP];
char *name[] =
{
"空手",
"带狼",
"带羊",
"带菜"
};
void search(int iStep)
{
int i;
if (a[iStep][0] + a[iStep][1] + a[iStep][2] + a[iStep][3] == 4)
{
for (i = 0; i < iStep; i++)
{
if (a[i][3] == 0)
{
printf("%s到对岸\n", name[b[i] + 1]);
}
else
{
printf("%s回本岸\n", name[b[i] + 1]);
}
}
printf("\n");
return;
}
for (i = 0; i < iStep; i++)
{
if (memcmp(a[i], a[iStep], sizeof(a[i])) == 0)
{
return;
}
}
if (a[iStep][1] != a[iStep][3] && (a[iStep][2] == a[iStep][1] || a[iStep][0] == a[iStep][1]))
{
return;
}
for (i = -1; i <= 2; i++)
{
b[iStep] = i;
memcpy(a[iStep + 1], a[iStep], sizeof(a[iStep + 1]));
a[iStep + 1][3] = 1 - a[iStep + 1][3];
if (i == -1)
{
search(iStep + 1);
}
else if (a[iStep][i] == a[iStep][3])
{
a[iStep + 1][i] = a[iStep + 1][3];
search(iStep + 1);
}
}
}
int main()
{
search(0);
return 0;
}
贵求解释.每一步的分析与描述.
答案:#include <stdio.h>
#include <stdlib.h>
#include <string.h> #define MAX_STEP 20
//index: 0 - 狼,1-羊,2-菜,3-农夫,value:0-本岸,1-对岸
int a[MAX_STEP][4];//用来表示每一步骤时狼,羊,菜,农夫的位置
int b[MAX_STEP]; //用来表示每一步骤农夫要带的东西,或空手过河,也就是方案
char *name[] = //农夫可能的四种过河方案
{
"空手",
"带狼",
"带羊",
"带菜"
};
void search(int iStep)
{
int i;
if (a[iStep][0] + a[iStep][1] + a[iStep][2] + a[iStep][3] == 4) //如果全部过岸了,打印结果,退出
{
for (i = 0; i < iStep; i++) //逐步打印过岸步骤
{
if (a[i][3] == 0)
//如果现在农夫在本岸,则要过对岸,b[i] + 1表示这一步骤农夫要带的东西,名字在name中
{
printf("%s到对岸\n", name[b[i] + 1]);
}
else //如果现在农夫在对岸,则要回本岸,b[i] + 1表示这一步骤农夫要带的东西,名字在name中
{
printf("%s回本岸\n", name[b[i] + 1]);
}
}
printf("\n"); //打印完方案,回车
return; //结束
}
//现有的方案,相邻步骤有没有无变化的,如果没有,说明有错误,退出,找下一方案
for (i = 0; i < iStep; i++)
{
/*
原型:extern int memcmp(void *buf1, void *buf2, unsigned int count);
用法:#include <string.h>
功能:比较内存区域buf1和buf2的前count个字节。
说明:
当buf1<buf2时,返回值<0
当buf1=buf2时,返回值=0
当buf1>buf2时,返回值>0
*/
if (memcmp(a[i], a[iStep], sizeof(a[i])) == 0)
{
return; //现有的方案,相邻步骤无变化,退出,找下一方案
}
}
//如果现有的方案,相邻步骤均有变化的,判断方案最后一步的结果是否有问题
//羊是关键,如果羊不和农夫在一起,羊就不能和菜在一起,羊也不能和狼在一起,
//所以,某一步iStep只要羊不和农夫在一起,有下列情况之一,就退出:
//1.羊就和菜在一起 2.羊和狼在一起
//这也是递归调用的出口之一
if (a[iStep][1] != a[iStep][3] && (a[iStep][2] == a[iStep][1] || a[iStep][0] == a[iStep][1]))
{
return; //不符合条件退出
}
for (i = -1; i <= 2; i++)
//当前步骤试探每一种方案,i说明方案
//-1:"空手";0:"带狼";1:"带羊";2:"带菜"
{
b[iStep] = i; //选择农夫要带的东西
/*
原型:extern void *memcpy(void *dest, void *src, unsigned int count);
用法:#include <string.h>
功能:由src所指内存区域复制count个字节到dest所指内存区域。
说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。
*/
//本步在上一步基础上修改,所以,先把上一步的内容拷贝到当前步中
memcpy(a[iStep + 1], a[iStep], sizeof(a[iStep + 1]));
//每一步都会有农夫在过河,这一步改变标志说明农夫过河:0-本岸,1-对岸
a[iStep + 1][3] = 1 - a[iStep + 1][3];
//递归在这里发生,在当前方案的基础上找下一步
if (i == -1) //如果空手过河,找下一步
{
search(iStep + 1); //找下一步骤
}
else if (a[iStep][i] == a[iStep][3])
//农夫带物过岸时
//当前步骤谁和农夫一起过河,下一步骤初始也和农夫在一起
{
a[iStep + 1][i] = a[iStep + 1][3]; //改变被带物的位置
search(iStep + 1); //找下一步骤
}
}
}
int main()
{
search(0); //从第0步开始
return 0;
}
你怎么不缩格呢??NND!
你出的分数太少了,问题比较繁琐..
上一个:C语言中怎么判定结构体数组中的某项元素为空
下一个:C语言中算术运算符和赋值运算符哪个优先级高?