FZOJ 2188 过河I(bfs)

Problem 2188 过河I

Accept: 107    Submit: 262
Time Limit: 3000 mSec    Memory Limit : 32768 KB

Problem Description

一天,小明需要把x只羊和y只狼运输到河对面。船可以容纳n只动物和小明。每次小明划船时,都必须至少有一只动物来陪他,不然他会感到厌倦,不安。不论是船上还是岸上,狼的数量如果超过羊,狼就会把羊吃掉。小明需要把所有动物送到对面,且没有羊被吃掉,最少需要多少次他才可以穿过这条河?

Input

有多组数据,每组第一行输入3个整数想x, y, n (0≤ x, y,n ≤ 200)

Output

如果可以把所有动物都送过河,且没有羊死亡,则输出一个整数:最少的次数。否则输出 -1 .

Sample Input

3 3 233 33 3

Sample Output

11-1

Hint

第一个样例

次数 船 方向 左岸 右岸(狼 羊)

0: 0 0 3 3 0 0

1: 2 0 > 1 3 2 0

2: 1 0 < 2 3 1 0

3: 2 0 > 0 3 3 0

4: 1 0 < 1 3 2 0

5: 0 2 > 1 1 2 2

6: 1 1 < 2 2 1 1

7: 0 2 > 2 0 1 3

8: 1 0 < 3 0 0 3

9: 2 0 > 1 0 2 3

10: 1 0 < 2 0 1 3

11: 2 0 > 0 0 3 3



又是隐试图的bfs,真心没脑子,不会搞啊。

可以把题目给出的条件建立一个三维模型(左右岸,当前岸的羊的数量,当前岸的狼的数量),具体的解释看代码。


代码如下:


#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int x,y,n;
bool mark[2][210][210];

struct node
{
	int x,y,pn,step; 
}temp,a;

int bfs()
{
	int i,j;
	queue<node>q;
	memset(mark,0,sizeof(mark));
	a.x=x;
	a.y=y;
	a.pn=0;//pn为0表示起始岸,pn为1表示对岸 
	a.step=0;
	q.push(a);
	mark[0][x][y]=1;
	while(!q.empty())
	{
		a=q.front();
		q.pop();
		if(a.x==x&&a.y==y&&a.pn==1)//把所有羊运到了对岸 
			return a.step;
		int pnx=x-a.x,pny=y-a.y;//当前岸的对岸的羊和狼的数量 
		for(i=0;i<=a.x;++i)//i表示要放入船的羊的数量 
		{
			for(j=0;j<=a.y;++j)//j表示要放入船的狼的数量 
			{
				if((i>=j||i==0)&&(pnx+i>=pny+j||pnx+i==0)&&(i+j>0&&i+j<=n))
				{
					if(!mark[1-a.pn][pnx+i][pny+j]&&(a.x-i>=a.y-j||a.x-i==0))
					{
						temp.x=pnx+i;
						temp.y=pny+j;
						temp.pn=1-a.pn;
						temp.step=a.step+1;
						q.push(temp);
						mark[temp.pn][temp.x][temp.y]=1;
					}
				}
			}
		}
	}
	return -1; 
}

int main()
{
	int ans;
	while(scanf("%d%d%d",&x,&y,&n)!=EOF)
	{
		ans=bfs();
		printf("%d\n",ans);
	}
	return 0;
}



你可能感兴趣的:(FZOJ 2188 过河I(bfs))