非常可乐

这道题目要用广搜,三个杯子互相倒水总共六种状态,注意剪枝条件的判定(总量为奇数时无法平分,杯子为空时无法倒出水,杯子为满时无法倒入水)

大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
Input
三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
Output
如果能平分的话请输出最少要倒的次数,否则输出"NO"。
Sample Input
7 4 3
4 1 3
0 0 0
Sample Output
NO
3
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#include<algorithm>
using namespace std;
struct list
{
	int a;
	int b;
	int c;
	int step;
};
bool check(int a,int b,int c);
bool book[101][101][101];
int flag;
int main()
{
	int s,n,m;
	while(scanf("%d%d%d",&s,&n,&m),s||n||m)
	{
		if(s&1)
			printf("NO\n");
		else
		{
			if(s==2*min(n,m))
				printf("1\n");
			else
			{
				flag=0;
				memset(book,false,sizeof(book));
				struct list node;
				queue<struct list> q;
				node.a=s;
				node.b=0;
				node.c=0;
				node.step=0;
				book[s][0][0]=true;
				q.push(node);
				while(!q.empty())
				{
					if(check(q.front().a,q.front().b,q.front().c))
						break;
					if(q.front().a!=0)
					{
						if(q.front().b!=n)
						{
							if(q.front().a>=n-q.front().b)                 //a   b
							{
								node.a=q.front().a-(n-q.front().b);
								node.b=n;
								node.c=q.front().c;
								node.step=q.front().step+1;
							}
							else
							{
								node.a=0;
								node.b=q.front().b+q.front().a;
								node.c=q.front().c;
								node.step=q.front().step+1;
							}
							if(!book[node.a][node.b][node.b])
							{
								book[node.a][node.b][node.b]=true;
								q.push(node);
							}
						}
						if(q.front().c!=m)
						{
							if(q.front().a>=m-q.front().c)                 //a   c
							{
								node.a=q.front().a-(m-q.front().c);
								node.c=m;
								node.b=q.front().b;
								node.step=q.front().step+1;
							}
							else
							{
								node.a=0;
								node.c=q.front().c+q.front().a;
								node.b=q.front().b;
								node.step=q.front().step+1;
							}
							if(!book[node.a][node.b][node.b])
							{
								book[node.a][node.b][node.b]=true;
								q.push(node);
							}
						}						
					}
					if(q.front().b!=0)	
					{
						if(q.front().a!=s)
						{
							if(q.front().b>=s-q.front().a)                 //b   a
							{
								node.b=q.front().b-(s-q.front().a);
								node.a=s;
								node.c=q.front().c;
								node.step=q.front().step+1;
							}
							else
							{
								node.b=0;
								node.a=q.front().a+q.front().b;
								node.c=q.front().c;
								node.step=q.front().step+1;
							}
							if(!book[node.a][node.b][node.b])
							{
								book[node.a][node.b][node.b]=true;
								q.push(node);
							}
						}
						if(q.front().c!=m)
						{
							if(q.front().b>=m-q.front().c)                 //b   c
							{
								node.b=q.front().b-(m-q.front().c);
								node.c=m;
								node.a=q.front().a;
								node.step=q.front().step+1;
							}
							else
							{
								node.b=0;
								node.c=q.front().c+q.front().b;
								node.a=q.front().a;
								node.step=q.front().step+1;
							}
							if(!book[node.a][node.b][node.b])
							{
								book[node.a][node.b][node.b]=true;
								q.push(node);
							}
						}						
					}			
					if(q.front().c!=0)
					{
						if(q.front().a!=s)
						{
							if(q.front().c>=s-q.front().a)                 //c    a
							{
								node.c=q.front().c-(s-q.front().a);
								node.a=s;
								node.b=q.front().b;
								node.step=q.front().step+1;
							}
							else
							{
								node.c=0;
								node.a=q.front().a+q.front().c;
								node.b=q.front().b;
								node.step=q.front().step+1;
							}
							if(!book[node.a][node.b][node.b])
							{
								book[node.a][node.b][node.b]=true;
								q.push(node);
							}
						}
						if(q.front().b!=n)
						{
							if(q.front().c>=n-q.front().b)                 //c    b
							{
								node.c=q.front().c-(n-q.front().b);
								node.b=n;
								node.a=q.front().a;
								node.step=q.front().step+1;
							}
							else
							{
								node.c=0;
								node.b=q.front().b+q.front().c;
								node.a=q.front().a;
								node.step=q.front().step+1;
							}
							if(!book[node.a][node.b][node.b])
							{
								book[node.a][node.b][node.b]=true;
								q.push(node);
							}
						}					
					}					
					q.pop();
				}
				if(q.empty())
					printf("NO\n");
				else
				{
					if(flag)
						printf("%d\n",q.front().step+1);
					else
						printf("%d\n",q.front().step);
				}					
			}			
		}		
	}
	return 0;
} 
bool check(int a,int b,int c)
{
	if(a!=0&&b!=0&&c==0&&a==b)
		return true;
	if(a!=0&&c!=0&&b==0&&a==c)
		return true;
	if(b!=0&&c!=0&&a==0&&b==c)
		return true;
	if(a!=0&&b!=0&&c!=0&&a+b==c)
	{
		flag=1;
		return true;
	}		
	if(a!=0&&b!=0&&c!=0&&a+c==b)
	{
		flag=1;
		return true;
	}
	if(a!=0&&b!=0&&c!=0&&c+b==a)
	{
		flag=1;
		return true;
	}
	return false;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值