BFS
#include<iostream>
#include<ctime>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<set>
#include<memory.h>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef int ElemType;
string w = "0000"; //人、狼、羊、白菜的初始状态
string state, tmpstate;
int path[20]; //存路径
//狼吃羊,羊吃白菜
bool Judge(string t)
{
if ((t[0] != t[1] && t[1] == t[2]) || (t[0] != t[2] && t[2] == t[3]))
return false;
return true;
}
//由二进制转化为十进制
int bit(string s)
{
return ((s[0]-'0')<<3) + ((s[1]-'0')<<2) + ((s[2]-'0')<<1) + (s[3]-'0');
}
void BFS()
{
memset(path, -1, sizeof(path));
queue<string> q; //记录多重选择
//加入初始状态
path[0] = 0;
q.push(w);
int now = 0, tmp = 0; //当前状态、临时状态
while (!q.empty() && path[15] == -1) //如果队列不为空或都没到对岸则继续搜索
{
//出队当前状态
state = q.front();
q.pop();
now = bit(state);
//人带其他行动
for (int i = 1; i <= 3; ++i) //分别判断人能否带狼、羊、白菜过河
{
tmpstate = state;
if(state[0] == state[i])
{
(tmpstate[0] == '0') ? (tmpstate[0] = '1', tmpstate[i] = '1') : (tmpstate[0] = '0', tmpstate[i] = '0');
tmp = bit(tmpstate);
//如果合法且不重复
if (Judge(tmpstate) && path[tmp] == -1)
{
q.push(tmpstate);
path[tmp] = now;
}
}
//人单独行动
tmpstate = state;
tmpstate[0] = (tmpstate[0] == '0' ? '1' : '0');
tmp = bit(tmpstate);
if (Judge(tmpstate) && path[tmp] == -1)
{
q.push(tmpstate);
path[tmp] = now;
}
}
}
}
string BtoS(int t)
{
string tmp = "";
while(t)
{
tmp += t%2 + '0';
t /= 2;
}
while(tmp.length() < 4)
tmp += '0';
return tmp;
}
void PrintPath()
{
string o = "1111";
for (int i = 15; i > 0; i = path[i])
{
string t = BtoS(path[i]); //转换后:菜羊狼人
if(t[3] == '0' && t[0] == '0' && o[3] == '1' && o[0] == '1')
cout << "人和菜过河" << endl;
else
if(t[3] == '1' && t[0] == '1' && o[3] == '0' && o[0] == '0')
cout << "人和菜回来" << endl;
else
if(t[3] == '0' && t[1] == '0' && o[3] == '1' && o[1] == '1')
cout << "人和羊过河" << endl;
else
if(t[3] == '1' && t[1] == '1' && o[3] == '0' && o[1] == '0')
cout << "人和羊回来" << endl;
else
if(t[3] == '0' && t[2] == '0' && o[3] == '1' && o[2] == '1')
cout << "人和狼过河" << endl;
else
if(t[3] == '1' && t[2] == '1' && o[3] == '0' && o[2] == '0')
cout << "人和狼回来" << endl;
else
if(t[3] == '0' && o[3] == '1')
cout << "人过河" << endl;
else
if(t[3] == '1' && o[3] == '0')
cout << "人回来" << endl;
o = t;
}
}
signed main()
{
BFS();
PrintPath();
return 0;
}
DFS
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<math.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
typedef int Status;
typedef int ElemType;
Status f[17]={0};//记录状态是否被搜过
int pre[17]; //记录每个合法状态的前一个状态
int geti(int i,int n){
//获取下一目标状态
if(n>>3==0){
return n+8+i;
}
else{
return n-8-i;
}
}
Status judge(int n){
//判断该状态是否合法
if(n<0)
return FALSE;
if(n>>3==1){
if(((n>>2)%2==0&&(n>>1)%2==0)||((n>>1)%2==0&&n%2==0))
return FALSE;
return TRUE;
}
else{
if(((n>>2)%2==1&&(n>>1)%2==1)||((n>>1)%2==1&&n%2==1))
return FALSE;
return TRUE;
}
}
void dfs(int n){
//深度优先搜索正确的过河方案
f[n]=1;
//PrintBit(n);
for(int i=1,j=0;i<=8;i<<=1,j++){
int x,y;
if((n>>3)%2!=(n>>j)%2&&i!=8)
continue;
if(i==8)
y=geti(0,n);
else
y=geti(i,n);
if(judge(y)&&!f[y]){
pre[y]=n;
dfs(y);
}
}
}
void PrintChar(int x){
if(x==0){
printf("初始状态\n");
return ;
}
if(x>>3==1&&pre[x]>>3==0)
printf("人过河,");
if(x>>3==0&&pre[x]>>3==1)
printf("人回去,");
if((x>>2)%2==1&&(pre[x]>>2)%2==0)
printf("狼过河,");
if((x>>2)%2==0&&(pre[x]>>2)%2==1)
printf("狼回去,");
if((x>>1)%2==1&&(pre[x]>>1)%2==0)
printf("羊过河,");
if((x>>1)%2==0&&(pre[x]>>1)%2==1)
printf("羊回去,");
if(x%2==1&&pre[x]%2==0)
printf("白菜过河,");
if(x%2==0&&pre[x]%2==1)
printf("白菜回去,");
printf("\n");
}
void PrintBit(int n){
//将十进制数转为四位二进制输出
for(int i=3;i>=0;i--)
printf("%d",(n>>i)%2);
printf(":");
PrintChar(n);
}
void PrintStep(int x){
if(x==0){
PrintBit(x);
return ;
}
PrintStep(pre[x]);
PrintBit(x);
}
int main()
{
dfs(0);
PrintStep(15);
return 0;
}