数据结构课设:三个野人和三个传教士(C实现)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mystery_guest/article/details/70148688
#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;
}

猜你喜欢

转载自blog.csdn.net/mystery_guest/article/details/70148688