欢迎访问binary的Blog   虚心使人进步,骄傲使人落后。

          W3CHINA Blog首页    管理页面    写新日志    退出



«September 2025»
123456
78910111213
14151617181920
21222324252627
282930


登录

用户名称:
登陆密码:
密码保存:


联系我
email: binaryluo(at)gmail.com

我的分类

日志更新

最新评论

留言板

Blog信息

 
blog名称:二进制-虚心使人进步,骄傲使人落后。
日志总数:42
评论数量:370
留言数量:88
访问次数:639861
建立时间:2005年2月19日




[算法设计与分析]人与兽安全过河问题
原创空间,  软件技术,  科学研究,  校园生活

binaryluo 发表于 2006/6/4 8:50:09

   题目:    有一条河,在河的左岸有3个人和3个野兽要过河。河里有一只船,该船每次最多可以装2个物体(人或兽)。在河两岸上如果人的数目小于兽的数目,人就被兽吃掉。请列出人和兽能安全过河所有方法。    算法分析:    将某一时刻河岸的整个状态抽象为一个结构体,而没一个状态会由下列5中情况派生出5个子状态:1个人过河,2个人过河,1个兽过河,2个兽过河,1个人和一个兽过河。对每一个子状态进行判断:如果左边和右边都有人,两边的人数必须分别大于等于两边的兽数;如果左边有人,右边没人,左边的人数必须大于左边兽数;如果左边没人,右边有人,右边的人数必须大于右边的兽数。考虑用五元组 (X,Y,U,V,Z)建立模型:X-左边人数,Y-左边兽数,U-右边人数,V-右边兽数,Z-船的位置。    算法描述: /* 状态节点 */ typedef struct _stNode { int hl, bl, hr, br; pos bp;     /* boat position */ struct _stNode *parent;} stNode; /* 人兽过河 */ bool humbst(stNode st, FILE *fp, void (*opt)(stNode sm, FILE *fp)){ bool rev = false;  do {  /* 该状态与初始状态相同的情况不操作 */  if (st.hl == N && st.bl == N && st.hr == 0 &&   st.br == 0 && st.bp == left && st.parent != NULL)   break;   /* 该状态与祖父状态相同的情况不操作 */  if (st.parent != NULL && st.parent->parent != NULL)  {   if ((st.hl == st.parent->parent->hl)    && (st.bl == st.parent->parent->bl)    && (st.hr == st.parent->parent->hr)    && (st.br == st.parent->parent->br)    && (st.bp == st.parent->parent->bp))    break;  }   /* 人数小于兽数的时候不满足 */  if ((st.hl != 0 && st.hr != 0 && (st.hl < st.bl || st.hr < st.br))   || (st.hl != 0 && st.hr == 0 && st.hl < st.bl)   || (st.hl == 0 && st.hr != 0 && st.hr < st.br))   break;   /* 中止状态 */  if (st.hl == 0 && st.bl == 0 && st.hr == N &&   st.br == N && st.bp == right)  {   opt(st, fp);   rev = true;   break;  }   /* 正常情况 */  opt(st, fp);  switch (st.bp)  {  case left:   rev = humbst_left(st, fp, stDisp);   break;   case right:   rev = humbst_right(st, fp, stDisp);   break;  } } while (false);  return rev;} bool humbst_left(stNode st, FILE *fp, void (*opt)(stNode sm, FILE *fp)){ bool rev = false; stNode st1, st2, st3, st4, st5;  if (st.hl >= 1) /* 将左边的一个人运到右边 */ {  st1.hl = st.hl - 1;  st1.bl = st.bl;  st1.hr = st.hr + 1;  st1.br = st.br;  st1.bp = right;  st1.parent = &st;  rev = humbst(st1, fp, opt); }  if (st.hl >= 2) /* 将左边的两个人运到右边 */ {  st2.hl = st.hl - 2;  st2.bl = st.bl;  st2.hr = st.hr + 2;  st2.br = st.br;  st2.bp = right;  st2.parent = &st;  rev = humbst(st2, fp, opt); }  if (st.bl >= 1) /* 将左边的一个兽运到右边 */ {  st3.hl = st.hl;  st3.bl = st.bl - 1;  st3.hr = st.hr;  st3.br = st.br + 1;  st3.bp = right;  st3.parent = &st;  rev = humbst(st3, fp, opt); }  if (st.bl >= 2) /* 将左边的两个兽运到右边 */ {  st4.hl = st.hl;  st4.bl = st.bl - 2;  st4.hr = st.hr;  st4.br = st.br + 2;  st4.bp = right;  st4.parent = &st;  rev = humbst(st4, fp, opt); }  if (st.hl >= 1 && st.bl >= 1) /* 将左边的一个人一个兽运到右边 */ {  st5.hl = st.hl - 1;  st5.bl = st.bl - 1;  st5.hr = st.hr + 1;  st5.br = st.br + 1;  st5.bp = right;  st5.parent = &st;  rev = humbst(st5, fp, opt); }  return rev;} bool humbst_right(stNode st, FILE *fp, void (*opt)(stNode sm, FILE *fp)){ bool rev = false; stNode st1, st2, st3, st4, st5;  if (st.hr >= 1) /* 将右边的一个人运到左边 */ {  st1.hl = st.hl + 1;  st1.bl = st.bl;  st1.hr = st.hr - 1;  st1.br = st.br;  st1.bp = left;  st1.parent = &st;  rev = humbst(st1, fp, opt); }  if (st.hr >= 2) /* 将右边的两个人运到左边 */ {  st2.hl = st.hl + 2;  st2.bl = st.bl;  st2.hr = st.hr - 2;  st2.br = st.br;  st2.bp = left;  st2.parent = &st;  rev = humbst(st2, fp, opt); }  if (st.br >= 1) /* 将右边的一个兽运到左边 */ {  st3.hl = st.hl;  st3.bl = st.bl + 1;  st3.hr = st.hr;  st3.br = st.br - 1;  st3.bp = left;  st3.parent = &st;  rev = humbst(st3, fp, opt); }  if (st.br >= 2) /* 将右边的两个兽运到左边 */ {  st4.hl = st.hl;  st4.bl = st.bl + 2;  st4.hr = st.hr;  st4.br = st.br - 2;  st4.bp = left;  st4.parent = &st;  rev = humbst(st4, fp, opt); }  if (st.hr >= 1 && st.br >= 1) /* 将右边的一个人一个兽运到左边 */ {  st5.hl = st.hl + 1;  st5.bl = st.bl + 1;  st5.hr = st.hr - 1;  st5.br = st.br - 1;  st5.bp = left;  st5.parent = &st;  rev = humbst(st5, fp, opt); }  return rev;}    humbest函数其实就是构造一个状态变迁图(树),然后用opt函数来对该图进行操作(比如说dfs)。   上面算法描述其实就是代码片断了,思路很清晰。我已经编译通过,只需自己添加opt函数和main函数就可以运行了。 


阅读全文(4212) | 回复(2) | 编辑 | 精华
 


回复:人与兽安全过河问题
原创空间,  软件技术,  科学研究,  校园生活

boa(游客)发表评论于2006/9/26 14:33:31

这个思维可是相当滴敏捷啊,我都一点看不懂 


个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


回复:人与兽安全过河问题
原创空间,  软件技术,  科学研究,  校园生活

DavidPotter(游客)发表评论于2006/6/4 16:40:15

个人感觉以状态为节点,找一条路径就好了,为什么搞得这么乱呢? 

个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除
 


» 1 »

发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 2.271 second(s), page refreshed 144794455 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号