文章目录
问题 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