一场比赛一道题【bfs】

B - 一共有两道题在说谎
Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

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 暴力枚举,只想到这一步,然后开始做,这道题,做了一下午,修修改改了三个多小时,样例才过去....

然后提交,wa,再想一遍思路,才发现可能一个特殊条件,加上,ac,比赛最后只有我一个ac(渣渣们比赛,大神勿喷..),但是也是比赛过后,才发现有个比这个简单的题,无语纠结中......

花了一下午,才解决了两个题目,其他的题的知识点都没接触过,两道简单题,自己也做得迷迷糊糊的,废话不说了,代码上写的够详细了.....

感觉自己的思路都混乱了,就这样过去了..赛场上都把注释看晕了,又重新补充了一下注释..........


题解:

标记数组,标记的是两种动物的数量,另外一维标记的是河岸的状态,之前有个蚂蚁回家的题目,也是三维标记了三个状态,这个比较灵活.视情况而定...

然后就是无脑的bfs 枚举了,好像还真没什么总结的........

注意题目要求,任何时候都要羊多于狼,不,还可以没有羊,也就是每次上船或者下船,都要对两个岸上(标记数组其实就记录着另外一个岸的状态)的数量进行判断,

严格执行入队前的操作,然后就等着最优解出现了,如果一直不出现,证明不存在,输出 -1....

本来想用优先队列,但是想了想,好像没什么地方需要优先,权值的累加都是平等的,没有可以优化的好像.........

然后就跑程序了...........


#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int v[205][205][5],x,y,n;
struct he
{
	int shep,wolf,river;//shep 羊,wolf 狼,river 河岸 
	int cnt;//次数 
}st,tp;
void bfs()
{
	memset(v,0,sizeof(v));
	v[x][y][0]=1;//起始状态 
	queue<he> q;
	if(x>=y||x==0)//如果羊不比狼少,或者没有羊
	{
		st.shep=x;st.wolf=y;
		st.river=0;st.cnt=0;
		q.push(st);
	}
	while(!q.empty())
	{
		st=q.front();q.pop();//取一个队里的状态 
		if(st.river==1&&st.shep==x&&st.wolf==y)//如果全部到了另外一个河岸 
		{
			printf("%d\n",st.cnt);
			return;
		}
		for(int i=0;i<=st.shep;++i)//把所有的状态全部枚举一遍,羊上船的数量 
		{
			for(int j=0;j<=st.wolf;++j)//改变的狼的数量,上船 
			{
				if(!(i+j!=0&&i+j<=n)||(i<j&&i!=0)) 
				//每次船上只能有 1-n 个动物,并且 羊>=狼或者没羊
				{
					continue;
				}
				if(st.shep-i<st.wolf-j&&st.shep-i!=0)
				//上船后,船所在岸的要满足 羊>=狼或者没羊
				{
					continue;
				}
				int ts=x-st.shep+i;//另外一个岸上的羊的数量 
				int tw=y-st.wolf+j;//另外一个岸上的狼的数量 
				int tr=!st.river;
				if(ts<tw&&ts!=0)//到了另外一个岸上的也要满足 
				{
					continue;
				}
				if(!v[ts][tw][tr])//状态未出现过.... 
				{
					tp.shep=ts;tp.wolf=tw;// 
					tp.river=tr;tp.cnt=st.cnt+1; // 
					q.push(tp);//符合条件入队 
					v[ts][tw][tr]=1;//标记 
				}
			}
		} 
	}
	printf("-1\n");//队空则证明不存在方案 
}

int main()
{
	while(~scanf("%d%d%d",&x,&y,&n))
	{
		bfs();//搜索 
	}
	return 0;
}


刚刚发现,好像羊的英文单词都写错了................晕死了....


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值