过河问题–搜索树

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

时间限制: 1 Sec 内存限制: 128 MB

题目描述

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

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

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

输入

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

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

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

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

输出

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

否则,输出No solution

样例输入

4
3
2
0 1
1 2

样例输出

0000
1010
0010
1011
0001
1101
0101
1111

后台数据(之一)

输入
输出

AC代码

#include<bits/stdc++.h>
using namespace std;


void go_next(string& s, int prime, int monitor) {
	if (s[monitor] == '1')
		s[monitor] = '0';
	else if (s[monitor] == '0')
		s[monitor] = '1';
	if (prime == -1)
		return;
	if (s[prime] == '1')
		s[prime] = '0';
	else if (s[prime] == '0')
		s[prime] = '1';

}

int main() {
	int n;
	cin >> n;
	int** array = new int* [n];
	for (int i = 0; i < n; i++)
		array[i] = new int[n];
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			array[i][j] = 0;
	bool ok = 0;

	int monitor;
	cin >> monitor;
	monitor = n - monitor - 1;

	int t;
	cin >> t;
	while (t--)
	{
		int t1, t2;
		cin >> t1 >> t2;
		array[n - 1 - t1][n - 1 - t2] = 1;
		array[n - 1 - t2][n - 1 - t1] = 1;
	}
	queue<string>search_queue;
	string start_node(n, '0'), end_node(n, '1');
	search_queue.push(start_node);
	map<string, string>parent;
	while (!search_queue.empty())
	{
		string cur_node = search_queue.front();
		search_queue.pop();
		if (cur_node == end_node)
		{
			ok = 1;
			break;
		}

		//for (int i = -1; i < n; ++i)
		for (int i = n - 1; i >= -1; i--)
		{
			if (i == monitor || (i != -1 && cur_node[i] != cur_node[monitor]))
				continue;
			string new_node = cur_node;
			go_next(new_node, i, monitor);
			bool flag = 1;
			for (int j = 0; flag && j < n - 1; j++)
				for (int k = j + 1; k < n; k++)
				{
					if (j == monitor || k == monitor)
						continue;
					if (new_node[j] == new_node[k] && array[j][k] && new_node[j] != new_node[monitor])
					{
						flag = 0;
						break;
					}

				}
			if (flag && parent.find(new_node) == parent.end()) {

				parent[new_node] = cur_node;
				search_queue.push(new_node);
			}
		}
	}


	if (ok) {
		stack<string>output;
		string cur_node = end_node;
		while (cur_node !=start_node)
		{
			output.push(cur_node);
			//cout << cur_node << endl;
			cur_node = parent[cur_node];
		}
		cout << start_node << endl;
		while (!output.empty())
		{
			cout << output.top() << endl;
			output.pop();
		}
	}
	else cout << "No solution" << endl;
	return 0;
}

谢谢朋友们!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曹无悔

请支持我的梦想!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值