逻辑题:假设河的同一侧有警察、强盗……

假设河的同一侧有警察、强盗、路人A、路人A的两个孩子(A1,A2)、路人B、路人B的两个孩子(B1、B2),他们想要安全过河,限制条件如下:
1、假设警察不在,强盗会杀死所有的跟他在一起的人
2、假设路人A离开,路人B和路人A的孩子在一起,路人A的孩子会死掉
3、假设路人B离开,路人A和路人B的孩子在一起,路人B的孩子会死掉
4、河面上有一条船,但一次最多可以容纳两人过河
5、只有警察、路人A、路人B会划船
请给出你的过河方案。

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

struct state
{
	int l[8];
	int r[8];
	int boat;
	state()
	{
		for (int i=0;i<8;i++)
			l[i]=1;
		memset(r,0,sizeof(r));
		boat=0;
	}
};

bool ok(state s)
{
	bool flag=true;
	for (int i=0;i<8;i++)
		if (!s.r[i])
		{
			flag=false;
			break;
		}
	return flag;
}

bool valid(state s)
{
	bool flag=true;
	//left valid
	if (!s.l[0] && s.l[1] && (s.l[2]||s.l[3]||s.l[4]||s.l[5]||s.l[6]||s.l[7]))
		flag=false;
	if (s.l[2] && !s.l[5] && s.l[6] && s.l[7])
		flag=false;
	if (s.l[5] && !s.l[2] && s.l[3] && s.l[4])
		flag=false;

	//right valid
	if (!s.r[0] && s.r[1] && (s.r[2]||s.r[3]||s.r[4]||s.r[5]||s.r[6]||s.r[7]))
		flag=false;
	if (s.r[2] && !s.r[5] && s.r[6] && s.r[7])
		flag=false;
	if (s.r[5] && !s.r[2] && s.r[3] && s.r[4])
		flag=false;

	return flag;
}

const char str[][100]={"警察","强盗","A","A1","A2","B","B1","B2"};
string path[100];
bool found=false;
map<string, bool> M;
string toString(state s)
{
	string temp;
	for (int i=0;i<8;i++)
	{
		temp+=s.l[i]+'0';
		temp+=s.r[i]+'0';
	}
	temp+=s.boat+'0';
	//cout << temp << endl;
	return temp;
}
void dfs(state s,int depth)
{
	if (M[toString(s)]) return;
	if (found) return;
	if (!valid(s)) return;
	if (ok(s))
	{
		for (int i=0;i<depth;i++)
		{
			if (i%2==0)
				cout << "left --> right : ";
			else
				cout << "left <-- right : ";
			cout << path[i] << endl;
		}
		cout << "DONE" << endl;
		found=true;
		return;
	}
	M[toString(s)]=true;
	if (!s.boat)//left
	{
		if (s.l[0])
		{
			state newState=s;
			newState.boat=s.boat^1;
			newState.l[0]=0;
			newState.r[0]=1;
			path[depth]=str[0];
			dfs(newState,depth+1);

			for (int i=0;i<8;i++)
				if (i!=0 && s.l[i])
				{
					state newState=s;
					newState.boat=s.boat^1;
					newState.l[i]=newState.l[0]=0;
					newState.r[i]=newState.r[0]=1;
					path[depth]=str[0];
					path[depth]+=" ";
					path[depth]+=str[i];
					dfs(newState,depth+1);
				}
		}
		if (s.l[2])
		{
			state newState=s;
			newState.boat=s.boat^1;
			newState.l[2]=0;
			newState.r[2]=1;
			path[depth]=str[2];
			dfs(newState,depth+1);

			for (int i=0;i<8;i++)
				if (i!=2 && s.l[i])
				{
					state newState=s;
					newState.boat=s.boat^1;
					newState.l[i]=newState.l[2]=0;
					newState.r[i]=newState.r[2]=1;
					path[depth]=str[2];
					path[depth]+=" ";
					path[depth]+=str[i];
					dfs(newState,depth+1);
				}
		}
		if (s.l[5])
		{
			state newState=s;
			newState.boat=s.boat^1;
			newState.l[5]=0;
			newState.r[5]=1;
			path[depth]=str[5];
			dfs(newState,depth+1);

			for (int i=0;i<8;i++)
				if (i!=5 && s.l[i])
				{
					state newState=s;
					newState.boat=s.boat^1;
					newState.l[i]=newState.l[5]=0;
					newState.r[i]=newState.r[5]=1;
					path[depth]=str[5];
					path[depth]+=" ";
					path[depth]+=str[i];
					dfs(newState,depth+1);
				}
		}
	}
	else//right
	{
		if (s.r[0])
		{
			state newState=s;
			newState.boat=s.boat^1;
			newState.r[0]=0;
			newState.l[0]=1;
			path[depth]=str[0];
			dfs(newState,depth+1);

			for (int i=0;i<8;i++)
				if (i!=0 && s.r[i])
				{
					state newState=s;
					newState.boat=s.boat^1;
					newState.r[i]=newState.r[0]=0;
					newState.l[i]=newState.l[0]=1;
					path[depth]=str[0];
					path[depth]+=" ";
					path[depth]+=str[i];
					dfs(newState,depth+1);
				}
		}
		if (s.r[2])
		{
			state newState=s;
			newState.boat=s.boat^1;
			newState.r[2]=0;
			newState.l[2]=1;
			path[depth]=str[2];
			dfs(newState,depth+1);

			for (int i=0;i<8;i++)
				if (i!=2 && s.r[i])
				{
					state newState=s;
					newState.boat=s.boat^1;
					newState.r[i]=newState.r[2]=0;
					newState.l[i]=newState.l[2]=1;
					path[depth]=str[2];
					path[depth]+=" ";
					path[depth]+=str[i];
					dfs(newState,depth+1);
				}
		}
		if (s.r[5])
		{
			state newState=s;
			newState.boat=s.boat^1;
			newState.r[5]=0;
			newState.l[5]=1;
			path[depth]=str[5];
			dfs(newState,depth+1);

			for (int i=0;i<8;i++)
				if (i!=5 && s.r[i])
				{
					state newState=s;
					newState.boat=s.boat^1;
					newState.r[i]=newState.r[5]=0;
					newState.l[i]=newState.l[5]=1;
					path[depth]=str[5];
					path[depth]+=" ";
					path[depth]+=str[i];
					dfs(newState,depth+1);
				}
		}
	}
}
int main()
{
	state init;
	dfs(init,0);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值