HDU 1495

题目链接:非常可乐


大家一定觉的运动以后喝可乐是一件很惬意的事情,但是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

令人头大的题啊!!!

求最少次数。。。用 bfs ,因为 有三个容器,所以有 6 种可以相互顷倒情况( a->b   a->s   b->a   b->s   s->a   s->b)

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring> 
using namespace std;
struct Node{
	int a;
	int b;
	int s;
	int t;//记录步数 
}e[105],st;
int a,b,s;
int vis[105][105];
int bfs()
{
	queue<Node>q;
	memset(vis,0,sizeof(vis));
	st.a = 0;
	st.b = 0;
	st.t = 0;
	st.s = s;
	q.push(st);
	vis[a][b] = 1;
	while(!q.empty())
	{
		Node u = q.front(),v;// 用 u 表示当前,用 v 表示下一次 a b s 体积 
		q.pop();
		if(u.a== s/2 && u.s == s/2)// a 和  s 中可乐体积 都是原容量的一半 
		{
			return u.t;
		}
		if(u.s && u.a != a)//s -> a
		{
			int c = a - u.a;
			if(u.s >= c)
			{
				v.a =a;
				v.s = u.s - c;
			}
			else {
				v.a = u.a + u.s;
				v.s = 0;
			}
			v.b = u.b;
			v.t = u.t + 1;
			if(!vis[v.a][v.b])
			{
				q.push(v);
				vis[v.a][v.b] = 1;
			}
		}
		if(u.s && u.b != b) // s -> b
		{
			int c = b - u.b;
			if(u.s >= c)
			{
				v.s = u.s - c;
				v.b = b;
			}
			else {
				v.b = u.b + u.s;
				v.s = 0;
			}
			v.a = u.a;
			v.t = u.t + 1;
			if(!vis[v.a][v.b])
			{
				q.push(v);
				vis[v.a][v.b] = 1;
			}
		}
		if(u.a && u.s != s)// a -> s
		{
			int c = s - u.s;
			if(u.a >= c)
			{
				v.s = s;
				v.a = u.a - c;
			}
			else {
				v.s = u.s + u.a;
				v.a = 0;
			}
			v.b = u.b;
			v.t = u.t + 1;
			if(!vis[v.a][v.b])
			{
				q.push(v);
				vis[v.a][v,b] = 1;
			} 
		}
		if(u.a && u.b != b) // a -> b
		{
			int c = b - u.b;
			if(u.a >= c)
			{
				v.b = b;
				v.a = u.a - c;
			} 
			else {
				v.b = u.b + u.a;
				v.a = 0;
			}
			v.s = u.s;
			v.t = u.t + 1;
			if(!vis[v.a][v.b])
			{
				q.push(v);
				vis[v.a][v.b] = 1;
			}
		}
		if(u.b && u.a != a)// b -> a
		{
			int c = a - u.a;
			if(u.b >= c)
			{
				v.a = a;
				v.b = u.b - c;
			}
			else {
				v.a = u.a + u.b;
				v.b = 0;
			}
			v.s = u.s;
			v.t = u.t + 1;
			if(!vis[v.a][v.b])
			{
				q.push(v);
				vis[v.a][v.b] = 1;
			}
		}
		if(u.b && u.s != s)//b->s
		{
			int c = s - u.s;
			if(u.b >= c)
			{
				v.s = s;
				v.b = u.b - c;
			}
			else {
				v.s = u.s + u.b;
				v.b = 0;
			}
			v.a = u.a;
			v.t = u.t + 1;
			if(!vis[v.a][v.b])
			{
				q.push(v);
				vis[v.a][v.b] = 1;
			}
		}
	}
	return 0;
}
int main()
{
	while(scanf("%d%d%d",&s,&a,&b),s||a||b)
	{
		if(s%2)
		{
			cout<<"NO"<<endl; // 如果是奇数 ,肯定不满足条件 
			continue;
		}
		if(a<b) swap(a,b); // 让 a 的容量大 
		int ans = bfs();
		if(ans)
		{
			cout<<ans<<endl;
		}
		else {
			cout<<"NO"<<endl;
		}
	}
	return 0;
}

忘了初始化!!!

改错改得脑阔疼!!!

不过 

从别人的博客还发现了另类的做法

非常可乐—数论

#include<cstdio>
#include<iostream>
using namespace std;
int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}
int main()
{
    int a,b,c;
    while(scanf("%d%d%d",&a,&b,&c),a+b+c)
    {
        a/=gcd(b,c);
        if(a&1)printf("NO\n");
        else printf("%d\n",a-1);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值