算法谜题系列1 狼羊人问题
来源:互联网 发布:大数据投资 编辑:程序博客网 时间:2024/05/05 07:27
有一个人,一只羊,一只狼,一捆菜(狼可以吃羊,羊可以吃菜,只有人在的情况,才避免吃的情况),准备过河。有一条船只能载两样东西过河(人也算是一样东西,只有人才会往返坐船,其它不会),如何过才会全部安全过河(没有吃的现象)?
分析:可用自动机方法来解决,一个状态可形式化表示为<p,s,w,c>,即people、sheep、wolf、cabbage的四元组,<1,1,1,1>表示最终的状态,<0,0,0,0>表示初始状态;定义动作集<+1,1,0,0>,<+1,0,1,0>,<+1,0,0,1>,<-1,0,0,0>,<-1,-1,0,0>,<-1,0,-1,0>,<-1,0,0,-1>;定义合法状态p=1||p=0&s=1&w=0&c=0||p=0&s=0&w=1;
这样每一个状态在初始状态s0<0,0,0,0>开始,都可以有4个分支,返回时也有4个分支,注意到每个分支不一定是有效的,所以这需要一个可达性检查的过程,主要的思路如下:
1.过河每次对应三个分支,若扩展的状态<p,s,w,c>中有任意一个p,s,w,c大于1的,矛盾。对于返回后的状态,若任意一个p,s,w,c小于0的,也矛盾。
2.扩展后的状态需满足题目限制条件,即<0,1,1,0>,<0,1,1,1>,<0,1,0,1>以及<1,0,0,1>,<1,0,0,0>,<1,0,1,0>(对岸的情况不满足)
遍历过程中要确保nextstate是新状态,这就需要对每个出现过的状态进行记录.
#include <iostream>#include <list>using namespace std;typedef struct state{int p;int s;int w;int c;};typedef struct pace{state p;pace* next;} ;bool operator == (const state& sa, const state& sb){ return sa.p == sb.p && sa.s == sb.s &&sa.w == sb.w && sa.c == sb.c;}state operator +(const state& t1,const state& action){ state sum; sum.p=t1.p+action.p; sum.s=t1.s+action.s; sum.w=t1.w+action.w; sum.c=t1.c+action.c; return sum;};typedef list<state> statelist;//f_state为状态集合statelist f_state;statelist h_state;state init_state={0,0,0,0};state end_state={1,1,1,1};state action_go[4]={{1,0,0,0},{1,1,0,0},{1,0,1,0},{1,0,0,1}};state action_back[4]={{-1,0,0,0},{-1,-1,0,0},{-1,0,-1,0},{-1,0,0,-1}};state invalid_state[6]={{0,1,1,1},{0,1,1,0},{0,1,0,1},{1,0,0,0},{1,0,0,1},{1,0,1,0}};bool isvalid(state& t1){if(t1.c>=2||t1.p>=2||t1.s>=2||t1.w>=2) return false;if(t1.c<=-1||t1.p<=-1||t1.s<=-1||t1.w<=-1)return false;for(int i=0;i<6;i++) if(t1==invalid_state[i]) return false; statelist::iterator it = h_state.begin(); for(;it!=h_state.end(); it++) { if((*it)==t1) return false; } return true;};void getnextstate(int step){ state t1=f_state.back(); f_state.pop_back(); if(t1==end_state) { cout<<step<<endl; return; } if(step%2==0){ for(int i=0;i<4;i++) { state nextstate; nextstate=t1+action_go[i]; if(isvalid(nextstate)) { cout<<t1.p<<","<<t1.s<<","<<t1.w<<","<<t1.c<<"+"<<action_go[i].p<<","<<action_go[i].s<<","<<action_go[i].w<<","<<action_go[i].c <<"-->"<<nextstate.p<<","<<nextstate.s<<","<<nextstate.w<<","<<nextstate.c<<endl; f_state.push_back(nextstate); h_state.push_back(nextstate);getnextstate(step+1); } }}else{for(int i=0;i<4;i++) { state nextstate; nextstate=t1+action_back[i]; if(isvalid(nextstate)) { cout<<t1.p<<","<<t1.s<<","<<t1.w<<","<<t1.c<<action_back[i].p<<","<<action_back[i].s<<","<<action_back[i].w<<","<<action_back[i].c <<"-->"<<nextstate.p<<","<<nextstate.s<<","<<nextstate.w<<","<<nextstate.c <<endl; f_state.push_back(nextstate); h_state.push_back(nextstate);getnextstate(step+1); } }}}int main(){ f_state.push_back(init_state); h_state.push_back(init_state); getnextstate(0); return 0;}
0 0
- 算法谜题系列1 狼羊人问题
- 算法系列-topk问题
- 算法谜题系列(一)
- 背包问题系列算法详解
- 背包问题系列算法详解
- 算法系列--荷兰国旗问题
- 算法刷题系列(1)leetcode349
- 字符串系列算法题
- AdaBoost算法系列1
- 算法系列1《DES》
- 算法系列(1)-数据结构
- 【算法系列-1】排序
- 66算法系列-66漫谈topK 问题
- 算法系列——N皇后问题
- 算法系列:妖怪与和尚过河问题
- [算法系列之十一]荷兰国旗问题
- 经典算法系列---hanoi塔问题
- 经典算法系列之n皇后问题
- 九度OJ 1375 陈博的完美主义 (枚举,细心细心)
- 一个简单的shell脚本程序(运用expr命令)
- hdu-2218-Don't be angry
- 日志如何打印异常堆栈信息。
- C++ prime plus 第六版 8.8-4
- 算法谜题系列1 狼羊人问题
- 44黑名单界面显示&&ListView的优化
- 身怀绝“技” —— 面试之我见
- 如何使用Hadoop实现不同复杂度的遥感产品算法
- 在Eclipse上搭建Android开发环境
- 黑马程序员:论多线程的正确使用姿势
- mac 下搭建android studio 1.0
- Qt解析XML文件(QDomDocument)
- gcd(swift)