农夫过河

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
using namespace std;
bool invalid[16];
int head[16];
int next[100];
bool vis[16];
string state[16];
int l,t;
int sum;
int path[30];
struct node
{
    int x,y,next;
    string method;
}edge[35];
void add(int x,int y,int j,int i)//建边
{
    l++;
    edge[l].x = x;edge[l].y = y;
    edge[l].next = head[x];head[x] = l;
    edge[l].method = "农夫";
    if (j == 0)
        edge[l].method = edge[l].method + "带着羊";
    else if (j == 1)
        edge[l].method = edge[l].method + "带着白菜";
    else if (j == 2)
        edge[l].method = edge[l].method + "带着狼";
    if (((i^8)>>3) == 1) edge[l].method += "从南岸到北岸"; else edge[l].method += "从北岸返回南岸";
}
void build()
{
    int tmp;
    for (int i=0;i<=15;i++)
    {
        for (int j=0;j<=2;j++)//表示在i的二进制表示中给第几位取反,也就是让这一位表示的物品到达河对岸
        {
            tmp = (i^8) ^ (1<<j);
            if (!invalid[tmp])
                add(i,tmp,j,i);//向i能走到的所有合法的点添加边
        }
    }
    for (int i=0;i<=15;i++)
    {
        if (!invalid[i] && !invalid[i^8])
            add(i,i^8,-1,i);
    }
}
void dfs(int x)//x表示当前走到的状态
{
    if (x == 15)//找到结果,输出方案
    {
        sum++;
        printf("方案%d:\n", sum);
        for (int i=0;i<t;i++)
        {
            cout<<"Step"<<i+1<<": "<<edge[path[i]].method<<"-->";
            cout<<state[edge[path[i]].y]<<endl;
        }
        cout<<endl;
        return ;
    }
    vis[x] = 1;
    for (int p = head[x];p;p=edge[p].next)//遍历图
        if (!vis[edge[p].y])
    {
        path[t++] = p;
        dfs(edge[p].y);
        t--;
    }
    vis[x] = 0;
}
int main()
{
    memset(invalid,0,sizeof(invalid));
    memset(vis,0,sizeof(vis));
    invalid[3] = invalid[5] = invalid[7] = invalid[8] = invalid[10] = invalid[12] = 1;//标记不合法状态
    //所有状态的中文描述
    state[0] = "农夫、狼、白菜和羊都在南岸";
    state[1] = "羊在北岸,农夫、狼和白菜在南岸";
    state[2] = "白菜在北岸,农夫、狼和羊在南岸";
    state[3] = "白菜和羊在北岸,农夫和狼在南岸";
    state[4] = "狼在北岸,农夫、白菜和羊在南岸";
    state[5] = "狼和羊在北岸,农夫和白菜在南岸";
    state[6] = "狼和白菜在北岸,农夫和羊在南岸";
    state[7] = "狼、白菜和羊在北岸,农夫在南岸";
    state[8] = "农夫在北岸,狼、白菜和羊在南岸";
    state[9] = "农夫和羊在北岸,狼和白菜在南岸";
    state[10] = "农夫和白菜在北岸,狼和羊在南岸";
    state[11] = "农夫、白菜和羊在北岸,狼在南岸";
    state[12] = "农夫和狼在北岸,羊和白菜在南岸";
    state[13] = "农夫、狼和羊在北岸,白菜在南岸";
    state[14] = "农夫、狼和白菜在北岸,羊在南岸";
    state[15] = "农夫、狼、白菜和羊都在北岸";
    build();//建图中的边,图中的节点编号为0~15,分别表示15种状态
    t = 0;
    dfs(0);//从起点开始深度优先搜索
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值