HDOJ 1495 非常可乐 (bfs)

题目链接:~( ̄▽ ̄~)(~ ̄▽ ̄)~


用bfs广搜,用2维数组used[102][102]来记录2杯子出现过的状态(判重),如果可乐量为奇数这种情况不可能分成相等的2份


code:

#include <stdio.h>
#include <string.h>
int s = 0, n = 0, m = 0, used[102][102], flag = 0;
typedef struct
{
	int a, b, c, count;
}node;
node step, quene[10000];
int bfs()
{
	int  a = 0, b = 0, c = 0, front = 0, rear = 0;
	int  a1 = 0, b1 = 0, c1 = 0, count = 0;
	quene[rear++] = step;
	while(front<rear)
	{
		step = quene[front++];
		a = step.a; b = step.b; c = step.c; count = step.count;
		if(a != s)//从别的地方到到a中
		{
			if(a+b>s)
			{
				a1 = s;
				b1 = (a+b)-s;
			}
			else
			{
				a1 = a+b;
				b1 = 0;
			}
			c1 = c;//从b倒水到a中
			if((a1 == s/2 && b1 == s/2) || (a1 == s/2 && c1 == s/2) || (b1 == s/2 && c1 == s/2))
			{
				flag = count+1;
				return 1;
			}
			if(!used[b1][c1])
			{
				step.a = a1; step.b = b1; step.c = c1; step.count = count+1;
				used[b1][c1] = 1;
				quene[rear++] = step;
			}
			if(a+c>s)
			{
				a1 = s;
				c1 = (a+c)-s;
			}
			else
			{
				a1 = a+c;
				c1 = 0;
			}
			b1 = b; //从c倒水到a中
			if((a1 == s/2 && b1 == s/2) || (a1 == s/2 && c1 == s/2) || (b1 == s/2 && c1 == s/2))
			{
				flag = count+1;
				return 1;
			}
			if(!used[b1][c1])
			{
				step.a = a1; step.b = b1; step.c = c1; step.count = count+1;
				used[b1][c1] = 1;
				quene[rear++] = step;
			}
		}
		if(b != n)//从另外2杯子的倒水到b中
		{
			if(a+b>n)
			{
				b1 = n;
				a1 = (a+b)-n;
			}
			else
			{
				b1 = a+b;
				a1 = 0;
			}
			c1 = c;//从a倒水到b
			if((a1 == s/2 && b1 == s/2) || (a1 == s/2 && c1 == s/2) || (b1 == s/2 && c1 == s/2))
			{
				flag = count+1;
				return 1;
			}
			if(!used[b1][c1])
			{
				step.a = a1; step.b = b1; step.c = c1; step.count = count+1;
				used[b1][c1] = 1;
				quene[rear++] = step;
			}
			if(c+b>n)
			{
				b1 = n;
				c1 = (b+c)-n;
			}
			else
			{
				b1 = b+c;
				c1 = 0;
			}
			a1 = a;//从c倒水到b
			if((a1 == s/2 && b1 == s/2) || (a1 == s/2 && c1 == s/2) || (b1 == s/2 && c1 == s/2))
			{
				flag = count+1;
				return 1;
			}
			if(!used[b1][c1])
			{
				step.a = a1; step.b = b1; step.c = c1; step.count = count+1;
				used[b1][c1] = 1;
				quene[rear++] = step;
			}
		}
		if(c != m)//从另外2杯子的倒水到c中
		{
			if(a+c>m)
			{
				c1 = m;
				a1 = (a+c)-m;
			}
			else
			{
				c1 = a+c;
				a1 = 0;
			}
			b1 = b;//从a倒水到c
			if((a1 == s/2 && b1 == s/2) || (a1 == s/2 && c1 == s/2) || (b1 == s/2 && c1 == s/2))
			{
				flag = count+1;
				return 1;
			}
			if(!used[b1][c1])
			{
				step.a = a1; step.b = b1; step.c = c1; step.count = count+1;
				used[b1][c1] = 1;
				quene[rear++] = step;
			}
			if(b+c>m)
			{
				c1 = m;
				b1 = (b+c)-m;
			}
			else
			{
				c1 = b+c;
				b1 = 0;
			}
			a1 = a;//从b倒水到c
			if((a1 == s/2 && b1 == s/2) || (a1 == s/2 && c1 == s/2) || (b1 == s/2 && c1 == s/2))
			{
				flag = count+1;
				return 1;
			}
			if(!used[b1][c1])
			{
				step.a = a1; step.b = b1; step.c = c1; step.count = count+1;
				used[b1][c1] = 1;
				quene[rear++] = step;
			}
		}
	}
	return 0;
}
int main()
{
	while(scanf("%d %d %d",&s,&n,&m), (n || s || m))
	{
		memset(used,0,sizeof(used));
		step.a = s; step.b = 0; step.c = 0; step.count = 0;
		used[0][0] = 1;
		if(s%2 != 0)//为奇数不可能
			printf("NO\n");
		else
		{
			if(bfs())
				printf("%d\n",flag);
			else
				printf("NO\n");
		}
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值