搜索树--板子题

这篇博客通过搜索树的方法详细介绍了如何解决三个经典问题:过河问题使用BFS求解,八数码问题寻找最少移动次数,以及计算国际象棋骑士的最短路径。每个问题都提供了题目描述、输入输出样例和解题代码。
摘要由CSDN通过智能技术生成

问题 A: 过河问题–搜索树

题目描述

多个囚犯参与者要过河,其中只有监管者一人可以划船。小船每次最多载两人过河。监管者不在时,已有积怨的囚犯可能会斗殴。请问他们该如何安全过河?

假设一开始所有人都在河的左岸,用0表示,如果成功过河,则到达河的右岸,用1表示。

请采用BFS求解,并输出过河过程。

输入

首先输入要过河的人数n(包括监管者和囚犯)

接着输入监管者的编号s(假设每个人的编号从0开始,编号最小的在最右边)

然后输入有积怨的囚犯的对数m

接下来m行,两两输入有积怨的囚犯编号

输出

如有解,输出划船过河方案,即每一步的状态,也就是每个人此时在河的左岸还是右岸。初始状态全部为0。

否则,输出No solution

样例输入1

4
3
2
0 1
1 2

样例输入2

5
4
2
1 3
0 1

样例输出1

0000
1010
0010
1011
0001
1101
0101
1111

样例输出2

00000
10010
00010
10011
00001
11001
01001
11101
01101
11111

代码

#include <iostream>
#include <queue>
#include <vector>
#include <stack>
using namespace std;

class node
{
   
public:
    int* boat;
    node* father;
    node(int n)
    {
   
        boat=new int[n];
        for(int i=0;i<n;i++)boat[i]=0;//可优化
    }
};

class solution
{
   
public:
    int num,boss,pairs;//过河的人数,监管者编号,有仇者对数
    int s1[10],s2[10];//有仇者关系数组
    vector<node*> visit;//已访问结点
    queue<node*> list;//结点队列,bfs
    bool is_same(node* temp1)//判断是否到达目标状态
    {
   
        for(int i=0;i<num;i++)
            if(temp1->boat[i]!=1)return false;
        return true;
    }
    bool is_same(node* temp1,node* temp2)//重载,判断两个状态是否相等
    {
   
        for(int i=0;i<num;i++)
            if(temp1->boat[i]!=temp2->boat[i])return false;
        return true;
    }
    void put_next(node* temp1,int i)//将子状态压入队列
    {
   
        /*初始化子结点*/
        node* subnode=new node(num);//应该在堆中开辟
        for(int j=0;j<num;j++)
            subnode->boat[j]=temp1->boat[j];
        subnode->father=temp1;
        /*确定子结点的情况*/
        int index1=num-boss-1;//boss物理坐标
        int index2=i;//数组第i位
        if(index2==index1){
   //boss自己过河的情况
            subnode->boat[index1]=subnode->boat[index1]==1?0:1;
        }else if(temp1->boat[index1]==temp1->boat[index2]){
   //boss和囚犯在河的同一边的情况
            subnode->boat[index1]=subnode->boat[index1]==1?0:1;
            subnode->boat[index2]=subnode->boat[index2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值