当前位置: 代码迷 >> 综合 >> HDU 1495 非常可乐【bfs】
  详细解决方案

HDU 1495 非常可乐【bfs】

热度:41   发布时间:2023-11-11 10:40:19.0

非常可乐

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


 

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

 

将三个容器内的可乐剩余容量看为三个坐标,即可转换为(x,y,z) 形态,然后就可以当做广搜来做。

 

题目所说的平分指的是包括可乐瓶本身在内的任意两个容器的可乐量相等,并且另外一个容器的剩余可乐容量为0.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
using namespace std;
#define LL long long
#define M(a,b) memset(a,b,sizeof(a))
const int MAXN = 1e2+5;
const int INF =  0x3f3f3f3f;
int n,s,m;
int vis[MAXN][MAXN][MAXN];
queue<pair<pair<int,int>, int > >q;///用pair代替结构体
void init()
{M(vis,0);while(!q.empty()) q.pop();
}
int bfs(int x,int y,int z)
{vis[x][y][z] = 1;q.push(make_pair(make_pair(x,y),z));while(!q.empty()){int x1 = q.front().first.first;int y1 = q.front().first.second;int z1 = q.front().second;if((y1==z1&&x1==0&&y1!=0)||(y1==x1&&z1==0&&y1!=0)||(x1==z1&&y1==0&&x1!=0))///任意两个容器相等,剩下一个容器的容量为0{return vis[x1][y1][z1] - 1;}q.pop();/*总共有六种倒可乐的情况,分别枚举即可1->21->32->12->33->13->2*/if(y1+x1<n)///1->2{if(vis[0][y1+x1][z1]==0){vis[0][y1+x1][z1] = vis[x1][y1][z1] +1;q.push(make_pair(make_pair(0,y1+x1),z1));}}else{if(vis[x1+y1-n][n][z1]==0){vis[x1+y1-n][n][z1] = vis[x1][y1][z1] +1;q.push(make_pair(make_pair(x1+y1-n,n),z1));}}if(x1+z1<m)///1->3{if(vis[0][y1][x1+z1]==0){vis[0][y1][x1+z1] = vis[x1][y1][z1] +1;q.push(make_pair(make_pair(0,y1),x1+z1));}}else{if(vis[x1+z1-m][y1][m]==0){vis[x1+z1-m][y1][m] = vis[x1][y1][z1] +1;q.push(make_pair(make_pair(x1+z1-m,y1),m));}}if(vis[y1+x1][0][z1]==0)///2->1{vis[y1+x1][0][z1] = vis[x1][y1][z1] +1;q.push(make_pair(make_pair(y1+x1,0),z1));}if(y1+z1<m)///2->3{if(vis[x1][0][y1+z1]==0){vis[x1][0][y1+z1] = vis[x1][y1][z1] +1;q.push(make_pair(make_pair(x1,0),z1+y1));}}else{if(vis[x1][y1+z1-m][m]==0){vis[x1][y1+z1-m][m] = vis[x1][y1][z1] +1;q.push(make_pair(make_pair(x1,y1+z1-m),m));}}if(vis[z1+x1][y1][0]==0)///3->1{vis[z1+x1][y1][0] = vis[x1][y1][z1] +1;q.push(make_pair(make_pair(z1+x1,y1),0));}if(y1+z1<n)///3->2{if(vis[x1][z1+y1][0]==0){vis[x1][z1+y1][0] = vis[x1][y1][z1] +1;q.push(make_pair(make_pair(x1,z1+y1),0));}}else{if(vis[x1][n][z1+y1-n]==0){vis[x1][n][z1+y1-n] = vis[x1][y1][z1] +1;q.push(make_pair(make_pair(x1,n),z1+y1-n));}}}return -1;
}
int main()
{while(scanf("%d %d %d",&s,&n,&m)&&s&&n&&m){init();if(s%2==1)///s必须是偶数{printf("NO\n");continue;}int ans = bfs(s,0,0);if(ans==-1){printf("NO\n");}else{printf("%d\n",ans);}}return 0;
}
//4 1 3
//
//4 0 0
//
//3 1 0
//1 0 3