算法谜题系列1 狼羊人问题
Posted 童话的守望者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法谜题系列1 狼羊人问题相关的知识,希望对你有一定的参考价值。
有一个人,一只羊,一只狼,一捆菜(狼可以吃羊,羊可以吃菜,只有人在的情况,才避免吃的情况),准备过河。有一条船只能载两样东西过河(人也算是一样东西,只有人才会往返坐船,其它不会),如何过才会全部安全过河(没有吃的现象)?
分析:可用自动机方法来解决,一个状态可形式化表示为<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;
以上是关于算法谜题系列1 狼羊人问题的主要内容,如果未能解决你的问题,请参考以下文章