#include<cstdio>
#include<iostream>
using namespace std;
struct riverside
{
int wildman1;
int churchman1;
int wildman2;
int churchman2;
int direction;
};
struct Boat
{
int go_side;
int wildman;
int churchman;
};
riverside side_start,side_end;
Boat boat;
Boat flag[20];//用数组记录
int dir[5][2]={0,1,1,0,1,1,2,0,0,2};//运输的方式
riverside vis[100];//用来标记运输方式是否和上一次运输一样,避免递归层数过多,造成栈溢出
bool judge_midofside(riverside side)//判断每次运输,岸边和对岸的情况是否合法
{
//cout<<side.wildman1<<" "<<side.churchman1<<endl<<side.wildman2<<" "<<side.churchman2<<endl;
if(side.wildman1<0||side.churchman1<0||side.wildman2<0||side.churchman2<0)
return false;
if((side.churchman1!=0&&side.wildman1>side.churchman1)||((side.churchman2!=0&&side.wildman2>side.churchman2)))
return false;
//cout<<side.wildman1<<" "<<side.churchman1<<endl<<side.wildman2<<" "<<side.churchman2<<endl;
return true;
}
bool judge_endofside(riverside side)
{
if(side.wildman1==side_end.wildman1&&side.wildman2==side_end.wildman2&&side.churchman1==side_end.churchman1&&side.churchman2==side_end.churchman2)
return true;
return false;
}
bool judge_equal(riverside s1,riverside s2)
{
if(s1.wildman1==s2.wildman1&&s1.churchman1==s2.churchman1&&s1.wildman2==s2.wildman2&&s2.churchman2==s2.churchman2&&s1.direction==s2.direction)
return true;
return false;
}
bool judge_vis(riverside side,int cnt)
{
//*cout<<cnt<<endl;
for(int i=0;i<cnt;i++)
if(judge_equal(side,vis[i]))
{
//cout<<side.wildman1<<" "<<side.churchman1<<" "<<side.wildman2<<" "<<side.churchman2<<endl;
return true;
}
return false;
}
int pos_cnt=0;
void dfs(riverside side,Boat boat,int cnt)
{
// pos_cnt++;
// if(pos_cnt>=10)
// return ;
//cout<<side.wildman1<<" "<<side.churchman1<<" "<<side.wildman2<<" "<<side.churchman2<<" "<<cnt<<endl;
if(judge_endofside(side))
{
printf("第%d种方法为:\n\n",++pos_cnt);
for(int i=0;i<cnt;i++)
{
printf("第%d次:\n",i+1);
flag[i].go_side==0?printf("向对岸运送:"):printf("从对岸运回:");
printf("传教士%d,野人%d。\n",flag[i].churchman,flag[i].wildman);
}
printf("\n");
return ;
}
vis[cnt]=side;
Boat pos_boat;
riverside pos_side;
for(int i=0;i<5;i++)
{
pos_boat.wildman=dir[i][0],pos_boat.churchman=dir[i][1];
pos_boat.go_side=1-boat.go_side;
if(boat.go_side)
{
pos_side.wildman1=side.wildman1-pos_boat.wildman;
pos_side.churchman1=side.churchman1-pos_boat.churchman;
pos_side.wildman2=side.wildman2+pos_boat.wildman;
pos_side.churchman2=side.churchman2+pos_boat.churchman;
}
else
{
pos_side.wildman1=side.wildman1+pos_boat.wildman;
pos_side.churchman1=side.churchman1+pos_boat.churchman;
pos_side.wildman2=side.wildman2-pos_boat.wildman;
pos_side.churchman2=side.churchman2-pos_boat.churchman;
}
pos_side.direction=pos_boat.go_side;
//cout<<side.wildman1<<" "<<side.churchman1<<endl<<side.wildman2<<" "<<side.churchman2<<endl;
//cout<<pos_side.wildman1<<" "<<pos_side.churchman1<<endl<<pos_side.wildman2<<" "<<pos_side.churchman2<<endl;
if(judge_midofside(pos_side)&&!judge_vis(pos_side,cnt))
{
// printf("****\n");
flag[cnt]=pos_boat;
//printf("**** %d\n",pos_boat.go_side);
dfs(pos_side,pos_boat,cnt+1);
//flag[cnt]=;
}
}
// else
// {
// //printf("****\n");
// Boat pos_boat;
// riverside pos_side;
// for(int i=0;i<5;i++)
// {
// pos_boat.wildman=dir1[i][0],pos_boat.churchman=dir1[i][1];
// pos_boat.go_side=1-boat.go_side;
// pos_side.wildman1=side.wildman1+pos_boat.wildman;
// pos_side.churchman1=side.churchman1+pos_boat.churchman;
// pos_side.wildman2=side.wildman2-pos_boat.wildman;
// pos_side.churchman2=side.churchman2-pos_boat.churchman;
// if(judge_midofside(pos_side)&&judge_vis(side,pos_side))
// {
// flag[cnt]=pos_boat;
// dfs(pos_side,pos_boat,cnt++);
// }
// }
// }
return ;
}
int main()
{
side_start.wildman1=3,side_start.churchman1=3;//初始状态,对岸0人,岸边3野人3传教士
side_start.wildman2=0,side_start.churchman2=0;
side_end.wildman1=0,side_end.churchman1=0;//末状态,对岸3野人3传教士,岸边0人
side_end.wildman2=3,side_end.churchman2=3;
boat.churchman=0,boat.wildman=0;//初始船的状态
boat.go_side=1;
side_start.direction=boat.go_side;
memset(flag,0,sizeof(flag));
memset(vis,0,sizeof(vis));
printf("方案为:\n\n");
dfs(side_start,boat,0);
return 0;
}
数据结构课设:三个野人和三个传教士(C实现)
最新推荐文章于 2021-05-23 22:17:39 发布