hdoj 1495 非常可乐 【bfs(互相倒水)】
2015-11-13 21:28
337 查看
非常可乐
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8104 Accepted Submission(s): 3248
[align=left]Problem Description[/align]
大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为。因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多。但seeyou的手中只有两个杯子,它们的容量分别是N 毫升和M 毫升 可乐的体积为S (S<101)毫升 (正好装满一瓶) ,它们三个之间可以相互倒可乐 (都是没有刻度的,且 S==N+M,101>S>0,N>0,M>0) 。聪明的ACMER你们说他们能平分吗?如果能请输出倒可乐的最少的次数,如果不能输出"NO"。
[align=left]Input[/align]
三个整数 : S 可乐的体积 , N 和 M是两个杯子的容量,以"0 0 0"结束。
[align=left]Output[/align]
如果能平分的话请输出最少要倒的次数,否则输出"NO"。
[align=left]Sample Input[/align]
7 4 3 4 1 3 0 0 0
[align=left]Sample Output[/align]
NO 3
[align=left]Author[/align]
seeyou
[align=left]Source[/align]
“2006校园文化活动月”之“校庆杯”大学生程序设计竞赛暨杭州电子科技大学第四届大学生程序设计竞赛
[align=left]Recommend[/align]
LL | We have carefully selected several similar problems for you: 1175 1253 1072 1372 1180
思路:
通过一个结构体来保存三个杯子里面的水的体积和倒水的次数,a来保存的是初始状态,temp保存的是变化过后的状态,然后通过bfs来进行广搜,搜索每一个状态a下的所有的能够达到的状态,然后和最终的结果进行比较,(并且是在没有被访问过的状态下),并且在倒过之后,将它对应的times加1,如果它现在所处的状态与所要的最终状态不相符,则将它放进队列,在下次当成初始状态进行广搜,如果符合最终状态,则将他和ans进行比较,要最小的倾倒次数!
代码:
#include <stdio.h> #include <string.h> #include <algorithm> #include <queue> #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() { queue<node>q; 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; }
相关文章推荐
- 【Unity实用小方法】开启游戏时播放一段动画
- 串的顺序存储结构
- 实现 implements后重写toString
- iOS如何提高tableView的性能
- 8)排序②排序算法之选择排序[1]直接选择排序
- Adaboost 算法的原理与推导
- plsql developer7.1.4 + instantclient_10_2 链接远程oracle数据库
- android 解决listview 内部有按键控件时,listview无法点击
- XMLDLL操作说明文档(一)
- MySQL, 创建一个只读用户和一个所有权限用户
- pdf转word工具
- hdu 1166 敌兵布阵【线段树】单点更新,区间求和
- Lock
- 8)排序①排序算法之交换排序[2]快速排序
- 阻力线和支撑线
- ascyhttpclient 使用心得
- Android:View中的performClick()触发条件
- 第1章 对象导论
- Mysql 存储过程
- Codeforces 293B