hdoj 1495 非常可乐 【bfs(互相倒水)】

非常可乐

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8104    Accepted Submission(s): 3248


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  1253  1072  1372  1180 
 
思路:
          通过一个结构体来保存三个杯子里面的水的体积和倒水的次数,a来保存的是初始状态,temp保存的是变化过后的状态,然后通过bfs来进行广搜,搜索每一个状态a下的所有的能够达到的状态,然后和最终的结果进行比较,(并且是在没有被访问过的状态下),并且在倒过之后,将它对应的times加1,如果它现在所处的状态与所要的最终状态不相符,则将它放进队列,在下次当成初始状态进行广搜,如果符合最终状态,则将他和ans进行比较,要最小的倾倒次数!

代码:

#include 
#include 
#include 
#include 
#define INF 0x3f3f3f3f
using namespace std;
int ans;
struct node
{
	int v[4];
	int times;
}a,temp;
int vis[105][105][105];
int e[4];
void change(int i,int j)//进行倾倒! 
{
	int sum=temp.v[i]+temp.v[j];
	if(sum>e[j])
	{
		temp.v[j]=e[j];
		temp.v[i]=sum-e[j];
	}
	else
	{
		temp.v[j]=sum;
		temp.v[i]=0;
	}
}
void bfs()
{
	queueq;
	a.v[1]=e[1];
	a.v[2]=0;
	a.v[3]=0;
	a.times=0;
	q.push(a);
	memset(vis,0,sizeof(vis));
	vis[e[1]][0][0]=1;//表示已经有过这个状态了! 
	while(!q.empty())
	{
		a=q.front();
		q.pop();
		for(int i=1;i<=3;i++)
		{
			for(int j=1;j<=3;j++)
			{
				if(i==j)
					continue;
				else
				{
					temp=a;
					change(i,j);
					if(!vis[temp.v[1]][temp.v[2]][temp.v[3]])
					{
						temp.times++;//
						if((temp.v[1]==e[1]/2&&temp.v[2]==e[1]/2)||(temp.v[1]==e[1]/2&&temp.v[3]==e[1]/2)||(temp.v[2]==e[1]/2&&temp.v[3]==e[1]/2))//注意最终的状态! 
						{
							if(ans>temp.times)
							{
								ans=temp.times;
							}
							continue;
						}
						vis[temp.v[1]][temp.v[2]][temp.v[3]]=1;
						q.push(temp);
					}
				}
			}
			
		}
	}
}
int main()
{
	while(scanf("%d%d%d",&e[1],&e[2],&e[3])&&(e[1]||e[2]||e[3]))
	{
		if(e[1]%2!=0)
		{
			printf("NO\n");
			continue;
		}
		ans=INF;
		bfs();
		if(ans==INF)
		{
			printf("NO\n");
		}
		else
		{
			printf("%d\n",ans);
		}
	}
	return 0;
}


你可能感兴趣的:(hd,oj,bfs)