社区
数据结构与算法
帖子详情
求助:修道士与野人问题
lwforever
2003-07-11 09:36:45
这是一个古典问题。假设有N个修道士和N个野人准备渡河,但只有一天能容纳C人的小船,为了防止野人吃掉修道士,要求无论在何处(即两岸、船上),修道士的人数不得少于野人的人数(除非修道士人数为0)。如果两种人都会划船,试设计一个程序,确定他们能否渡过河去,若能,则给出一个小船来回次数最少的最佳方案,并打印出船来回的状态及野人和修道士人数变化状态
...全文
550
8
打赏
收藏
求助:修道士与野人问题
这是一个古典问题。假设有N个修道士和N个野人准备渡河,但只有一天能容纳C人的小船,为了防止野人吃掉修道士,要求无论在何处(即两岸、船上),修道士的人数不得少于野人的人数(除非修道士人数为0)。如果两种人都会划船,试设计一个程序,确定他们能否渡过河去,若能,则给出一个小船来回次数最少的最佳方案,并打印出船来回的状态及野人和修道士人数变化状态
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
8 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
cygandti
2003-07-24
打赏
举报
回复
程序写的很好!嘿嘿
Richardhu
2003-07-22
打赏
举报
回复
而且答案可能不唯一。
Richardhu
2003-07-22
打赏
举报
回复
代码看了头痛,这应是一道人工智能的题。可以用一般图搜索法,关键在与构造数据结构。你可以看看有关人工智能方面的书,你会看见一摸一样的题。
Skt32
2003-07-20
打赏
举报
回复
struct INFO
{
int nSavage; // 岸边野人的数量 开始为3 全部到对岸为0
int nBoanerges; // 岸边传教士的数量 开始为3 全部到对岸为0
int nSide; // 船的位置 在此岸为-1 彼岸为1
int nMoveSavage; // 渡河的野人的数量,用于递归时记录操作状态
int nMoveBoanerges; // 渡河的传教士的数量,用于递归时记录操作状态
INFO* pPrevious;
INFO* pNext;
};
// 判断是否有下一个满足条件的渡河方案
bool GetNextMove(INFO* pInfo)
{
// 渡船的优先顺序
// 此岸数量多优先,野人优先,彼岸数量少优先,传教士优先。
const int nStoreCount = 5;
struct STORE
{
int nSavage;
int nBoanerges;
};
STORE listStore[nStoreCount];
if (pInfo->nSide == -1)
{
listStore[0].nSavage = 2;
listStore[0].nBoanerges = 0;
listStore[1].nSavage = 1;
listStore[1].nBoanerges = 1;
listStore[2].nSavage = 0;
listStore[2].nBoanerges = 2;
listStore[3].nSavage = 1;
listStore[3].nBoanerges = 0;
listStore[4].nSavage = 0;
listStore[4].nBoanerges = 1;
}
else
{
listStore[0].nSavage = 0;
listStore[0].nBoanerges = 1;
listStore[1].nSavage = 1;
listStore[1].nBoanerges = 0;
listStore[2].nSavage = 0;
listStore[2].nBoanerges = 2;
listStore[3].nSavage = 1;
listStore[3].nBoanerges = 1;
listStore[4].nSavage = 2;
listStore[4].nBoanerges = 0;
}
int iStart;
if (pInfo->nMoveSavage == 0 && pInfo->nMoveBoanerges == 0)
{
iStart = 0;
}
else
{
for (iStart=0; iStart<nStoreCount; iStart++)
{
if (pInfo->nMoveSavage == listStore[iStart].nSavage && pInfo->nMoveBoanerges == listStore[iStart].nBoanerges)
break;
}
iStart++;
}
if (iStart < nStoreCount)
{
int i;
for (i=iStart; i<nStoreCount; i++)
{
int nSideSavage = pInfo->nSavage + listStore[i].nSavage * pInfo->nSide;
int nSideBoanerges = pInfo->nBoanerges + listStore[i].nBoanerges * pInfo->nSide;
int nBesideSavage = 3 - nSideSavage;
int nBesideBoanerges = 3 - nSideBoanerges;
// 传教士数量大于等于野人或为零
if ((nSideSavage<=nSideBoanerges || nSideBoanerges == 0) &&
(nBesideSavage<=nBesideBoanerges || nBesideBoanerges == 0) &&
nSideSavage>=0 && nSideBoanerges>=0 && nBesideSavage>=0 && nBesideBoanerges>=0)
{
// 如果本此解等于上次,放弃
if (pInfo->pPrevious != NULL)
{
if (pInfo->pPrevious->nMoveBoanerges == listStore[i].nBoanerges &&
pInfo->pPrevious->nMoveSavage == listStore[i].nSavage)
continue;
}
break;
}
}
if (i < nStoreCount)
{
pInfo->nMoveSavage = listStore[i].nSavage;
pInfo->nMoveBoanerges = listStore[i].nBoanerges;
return true;
}
}
return false;
}
// 递归函数
bool Ship(INFO* pInfo)
{
if (GetNextMove(pInfo))
{
INFO* pNew = new INFO;
pNew->nSavage = pInfo->nSavage + pInfo->nMoveSavage * (pInfo->nSide);
pNew->nBoanerges = pInfo->nBoanerges + pInfo->nMoveBoanerges * (pInfo->nSide);
pNew->nSide = (pInfo->nSide) * (-1);
pNew->pPrevious = pInfo;
pNew->pNext = NULL;
pNew->nMoveSavage = 0;
pNew->nMoveBoanerges = 0;
pInfo->pNext = pNew;
if (pNew->nSavage == 0 && pNew->nBoanerges == 0) return true; // 完成
return Ship(pNew);
}
else
{
INFO* pPre = pInfo->pPrevious;
if (pPre == NULL) return false; // 无解
delete pInfo;
pPre->pNext = NULL;
return Ship(pPre);
}
return true;
}
int main(int argc, char* argv[])
{
INFO* pHead = new INFO;
pHead->nSavage = 3;
pHead->nBoanerges = 3;
pHead->nSide = -1;
pHead->pPrevious = NULL;
pHead->pNext = NULL;
pHead->nMoveSavage = 0;
pHead->nMoveBoanerges = 0;
if (Ship(pHead))
{
printf("渡河过程如下:\n");
INFO* pInfo = pHead;
while (pInfo->pNext)
{
printf("渡河方向:%s 人数:野人%d - 传教士%d 此岸野人数:%d, 传教士数:%d\n",
(pInfo->nSide == -1) ? "-->" : "<--", pInfo->nMoveSavage,
pInfo->nMoveBoanerges, pInfo->nSavage, pInfo->nBoanerges);
pInfo = pInfo->pNext;
}
printf("渡河完成。");
}
else
{
printf("此题无解!");
}
// 删除链表
while (pHead)
{
INFO* pTemp = pHead->pNext;
delete pHead;
pHead=pTemp;
}
pHead = NULL;
printf("请结束程序。");
return 0;
}
程序结果
渡河过程如下:
渡河方向:--> 人数:野人2 - 传教士0 此岸野人数:3, 传教士数:3
渡河方向:<-- 人数:野人1 - 传教士0 此岸野人数:1, 传教士数:3
渡河方向:--> 人数:野人2 - 传教士0 此岸野人数:2, 传教士数:3
渡河方向:<-- 人数:野人1 - 传教士0 此岸野人数:0, 传教士数:3
渡河方向:--> 人数:野人0 - 传教士2 此岸野人数:1, 传教士数:3
渡河方向:<-- 人数:野人1 - 传教士1 此岸野人数:1, 传教士数:1
渡河方向:--> 人数:野人0 - 传教士2 此岸野人数:2, 传教士数:2
渡河方向:<-- 人数:野人1 - 传教士0 此岸野人数:2, 传教士数:0
渡河方向:--> 人数:野人2 - 传教士0 此岸野人数:3, 传教士数:0
渡河方向:<-- 人数:野人0 - 传教士1 此岸野人数:1, 传教士数:0
渡河方向:--> 人数:野人1 - 传教士1 此岸野人数:1, 传教士数:1
渡河完成。请结束程序。Press any key to continue
baizhao
2003-07-19
打赏
举报
回复
是不是可以用状态转移矩阵?
BlueSky2008
2003-07-12
打赏
举报
回复
多个人一样解,算法设计的总思路是每次过河的人尽可能地多,回来的人尽可能地少,当n>m,c≥2的时候总是有解。
caesar22
2003-07-12
打赏
举报
回复
是不是问题没有描述清楚啊,应该是修道士与野人是分别在两岸的吧。
ZhangYv
2003-07-11
打赏
举报
回复
看看这个,搜索http://expert.csdn.net/Expert/topic/1715/1715994.xml?temp=.6633112
依靠自我
我们的生活日新月异地发展着,可是,它也每天都向我们提出新的
问题
,我们需要一种怎样的思想支持呢?我们每个人怎样才能走向成功呢?“他山之石,可以攻玉”,这就是我编译爱默生的原因所在。 为了读者...
英语词根词缀记忆法
但,我们还应该看到,还有相当一部分单词的词义并不这样直接明了,有时词义与词根、词缀常规意义相差很大,无法再套用前面"复合意义"推理判断单词的含义了,比如下面这些单词: 1) port (拿、带)--report 报告、...
英语词根词缀记忆大全
3、ab-,ac-,ad-,af-,ag-,an-,ap-,ar-,as-,at-等加在同辅音字母的词根前,表示”一再”等加强意。的,”流行于人民之中的” =]流行的,传染的,流行病,时疫。democracy[demo人民,cracy统治,”人民统治”=人民做主=]民主,...
jetty-xml-9.4.44.v20210927.jar中文文档.zip
1、压缩文件中包含: 中文文档、jar包下载地址、Maven依赖、Gradle依赖、源代码下载地址。 2、使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 3、特殊说明: (1)本文档为人性化翻译,精心制作,请放心使用; (2)只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; (3)不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 4、温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件。 5、本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册。
tephra-api-0.6.0.jar中文文档.zip
1、压缩文件中包含: 中文文档、jar包下载地址、Maven依赖、Gradle依赖、源代码下载地址。 2、使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 3、特殊说明: (1)本文档为人性化翻译,精心制作,请放心使用; (2)只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; (3)不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 4、温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件。 5、本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册。
数据结构与算法
33,028
社区成员
35,336
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章