Hduoj1459【深搜】

/*非常可乐
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6149    Accepted Submission(s): 2490

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

Author
seeyou

Source
“2006校园文化活动月”之“校庆杯”大学生程序设计竞赛暨杭州电子科技大学第四届大学生程序设计竞赛 

Recommend
LL   |   We have carefully selected several similar problems for you:  1175 1072 1372 1180 1016 
*/
#include<stdio.h>
#include<string.h>
int vis[101][101], v[3], aim;
struct node
{
	int num, vo[3];
}q[10010];
int min(int x, int y)
{
	return x<y?x:y;
}
int bfs()
{
	int front  = 0, rear = 0, i, j;
	node now, next;
	q[0].vo[0] = v[0];
	q[0].vo[1] = q[0].vo[2] = q[0].num = 0;
	vis[v[0]][0] = 1;//mark the beganing
	rear++;
	while(front < rear)
	{
		now = q[front++];
		i = 0;
		if(now.vo[0] == aim)
		i++;
		if(now.vo[1] == aim)
		i++;
		if(now.vo[2] == aim)
		i++; 
		if(i >= 2)//succeed to part
		return now.num;
		for(i = 0; i < 3; ++i)
		{
			for(j = 0; j < 3; ++j)
			if(i != j)//which to pour which to get
			{
				int temp = min(now.vo[i], v[j] - now.vo[j]);//decide how much to pour
				for(int k = 0; k < 3; ++k)
					next.vo[k] = now.vo[k];
				next.vo[i] -= temp;
				next.vo[j] += temp;
				if(!vis[next.vo[0]][next.vo[1]])
				{
					vis[next.vo[0]][next.vo[1]] = 1;
					next.num = now.num + 1;
					q[rear++] = next;
				}
			}
		}
	}
	return -1;
}
int main()
{
	int i ;
	while(scanf("%d%d%d", &v[0], &v[1], &v[2]) != EOF)
	{
		if(v[0] == 0 && v[1] == 0 && v[2] == 0)
		break;
		if(v[0] & 1)
		{
			printf("NO\n");
			continue;
		}
		aim = v[0]>>1;
		memset(vis, 0, sizeof(vis));
		i = bfs();
		if(i != -1)
		printf("%d\n", i);
		else
		printf("NO\n");
	}
	return 0;
}


题意:给出一瓶可乐容量为s, 再给出2个杯子容量分别为m, n,且m+n = s,现在要求将容量为s的可乐平分出2杯s/2的可乐,三个杯子可以互相倒,问是否能分出两杯s/2一样的可乐的杯子。

思路:首先这三个杯子可以互相倒,所以总体思路就是不断的从可乐瓶中倒出可乐,再倒回去,看其中一个大的杯子能否获得s/2的可乐。并且每倒一次就要将这种情况标记一下。这里要注意的就是最后可乐瓶中的可乐也必须是s/2的可乐。

你可能感兴趣的:(Hduoj1459【深搜】)