搜索练习10/hdu.edu.cn/problem1495 非常可乐,bfs+回溯
来源:互联网 发布:知乎广州it培训机构 编辑:程序博客网 时间:2024/06/07 19:00
http://acm.hdu.edu.cn/showproblem.php?pid=1495
非常可乐
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 14272 Accepted Submission(s): 5712
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 34 1 30 0 0
Sample Output
NO3
第一次做到水问题,代码有点长,不过很好理解。都是根据自己想法打的代码。
题意就不多说,都懂的。题意有一点就是:两杯水相等并且另一杯水量为0才行。
思路:只有3个杯子,1>2,1>3,2>3,2>1,2>3,3>1;">"表示谁往谁水。总共6种情况。bfs解法。
附上我的AC代码(内存1.6MB,时间46ms,长度4755):觉得这道题我应该练一下回溯的(有好多题需要输出过程的,很有必要写一下),所以,我就画蛇添足,写了回溯,哈哈,不好意思,代码有点长,但大部分是重复的。
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<vector>#include<map>#include<string>#define LL long long#define eps 1e-8using namespace std;const int mod = 1e7+7;const int INF = 1e8;const int inf = 0x3f3f3f3f;const int maxx = 100100;const int N = 1050;map<int,int>ma;//map标记int n,m,k;struct node{ int x,y,z,step;// int a1[100],a2[100],a3[100];//回溯,存过程};node p1,p2;int bfs(){ queue<node>q; p1.x=n,p1.y=0,p1.z=0,p1.step=0; ma[p1.x*1e6+p1.y*1e3+p1.z]=1; q.push(p1); while(!q.empty()) { p1=q.front(); q.pop(); if(p1.y!=m&&p1.x)//1>2:1往2倒水,下同。 { p2.step=p1.step+1; p2.z=p1.z; if(p1.y+p1.x>=m) { p2.y=m; p2.x=p1.y+p1.x-m; } else { p2.y=p1.y+p1.x; p2.x=0; } if(!ma[p2.x*1e6+p2.y*1e3+p2.z]) {// p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z; ma[p2.x*1e6+p2.y*1e3+p2.z]=1; if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y)) return p2.step; q.push(p2); } } if(p1.z!=k&&p1.x)//1>3 { p2.y=p1.y; p2.step=p1.step+1; if(p1.z+p1.x>=k) { p2.z=k; p2.x=p1.z+p1.x-k; } else { p2.z=p1.z+p1.x; p2.x=0; } if(!ma[p2.x*1e6+p2.y*1e3+p2.z]) {// p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z; ma[p2.x*1e6+p2.y*1e3+p2.z]=1; if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y)) return p2.step; q.push(p2); } } if(p1.z!=k&&p1.y)//2>3 { p2.x=p1.x; p2.step=p1.step+1; if(p1.y+p1.z>=k) { p2.z=k; p2.y=p1.y+p1.z-k; } else { p2.z=p1.y+p1.z; p2.y=0; } if(!ma[p2.x*1e6+p2.y*1e3+p2.z]) {// p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z; ma[p2.x*1e6+p2.y*1e3+p2.z]=1; if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y)) return p2.step; q.push(p2); } } if(p1.y)//2>1 { p2.z=p1.z; p2.step=p1.step+1; p2.x=p1.y+p1.x; p2.y=0; if(!ma[p2.x*1e6+p2.y*1e3+p2.z]) {// p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z; ma[p2.x*1e6+p2.y*1e3+p2.z]=1; if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y)) return p2.step; q.push(p2); } } if(p1.z)//3>1 { p2.y=p1.y; p2.step=p1.step+1; p2.x=p1.z+p1.x; p2.z=0; if(!ma[p2.x*1e6+p2.y*1e3+p2.z]) {// p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z; if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y)) return p2.step; ma[p2.x*1e6+p2.y*1e3+p2.z]=1; q.push(p2); } } if(p1.y!=m&&p1.z)//3>2 { p2.x=p1.x; p2.step=p1.step+1; if(p1.y+p1.z>=m) { p2.y=m; p2.z=p1.y+p1.z-m; } else { p2.y=p1.y+p1.z; p2.z=0; } if(!ma[p2.x*1e6+p2.y*1e3+p2.z]) {// p2.a1[p2.step]=p2.x,p2.a2[p2.step]=p2.y,p2.a3[p2.step]=p2.z; if((p2.x==p2.y&&p2.x&&!p2.z)||(p2.y&&p2.y==p2.z&&!p2.x)||(p2.x&&p2.x==p2.z&&!p2.y)) return p2.step; ma[p2.x*1e6+p2.y*1e3+p2.z]=1; q.push(p2); } } } return -1;}int main(){ while(~scanf("%d%d%d",&n,&m,&k)) { if(n==0&&m==0&&k==0) break; ma.clear(); int ans=bfs(); if(ans==-1) printf("NO\n"); else printf("%d\n",ans);// for(int i=1;i<=p2.step;i++)// printf("%d %d %d\n",p2.a1[i],p2.a2[i],p2.a3[i]); }}
因为自己代码又丑又长,再附上其他人的高级代码(内存6MB,时间748ms,长度1781):
# include <stdio.h># include <queue># include <string.h>using namespace std;#define max 105struct node{ int cpu[3];//用数组方便对容器进行操作 int step;};int full[3];//设置容器的容量 int dir[6][2] = {{0,1}, {0,2}, {1,0}, {1,2}, {2,0}, {2,1}};int v[max][max][max] = {0};//标记数组,判断是否重复 void turn(int &a, int &b, int fullb)//将a的水倒入b { if( a+b < fullb) { b += a; a = 0; } else { a -= (fullb - b); b = fullb; }}int PAN(node s)//因为三个杯子互相倒,任意两个杯子都有可能存放一半的水 { if(s.cpu[0] + s.cpu[1] == full[0] && s.cpu[0] == s.cpu[1]) return 1; if(s.cpu[0] + s.cpu[2] == full[0] && s.cpu[0] == s.cpu[2]) return 1; if(s.cpu[1] + s.cpu[2] == full[0] && s.cpu[1] == s.cpu[2]) return 1; return 0; }int BFS(node s){ queue<node>Q; Q.push(s); node q; while(Q.size()) { s = Q.front(); Q.pop(); if(PAN(s)) return s.step; for(int i = 0; i<6; i++) { q = s; turn(q.cpu[dir[i][0]], q.cpu[dir[i][1]], full[dir[i][1]]); if(v[ q.cpu[0] ][q.cpu[1]][q.cpu[2]] == 0) { q.step+=1; v[ q.cpu[0] ][q.cpu[1]][q.cpu[2]] = 1; Q.push(q); } } } return -1;}int main(void){ node s; while(scanf("%d%d%d",&full[0], &full[1], &full[2]), full[0] + full[1]+full[2]) { s.cpu[0] = full[0]; s.step = s.cpu[1] = s.cpu[2] = 0; memset(v, 0, sizeof(v)); int ans = BFS(s); if(ans == -1) printf("NO\n"); else printf("%d\n",ans); } return 0;}
0 0
- 搜索练习10/hdu.edu.cn/problem1495 非常可乐,bfs+回溯
- HDU - 1495 非常可乐(15.10.10 搜索专题)bfs
- HDU 1495 非常可乐【隐式图搜索,BFS】
- 非常可乐BFS搜索
- HDU 1495 非常可乐 广度优先搜索(BFS)
- 搜索专题(BFS)HDU 1495-非常可乐
- HDU 1495 非常可乐 bfs状态空间搜索
- hdu 1495 bfs 非常可乐
- hdu 1495 非常可乐 BFS
- hdu 1495 非常可乐 bfs
- hdu 1495 非常可乐 (bfs)
- 非常可乐 hdu 1495 BFS
- hdu 1495非常可乐 bfs
- HDU 1495 非常可乐 BFS
- hdu 1495 非常可乐 (bfs)
- [bfs] HDU 1495 非常可乐
- BFS-HDU-1495-非常可乐
- hdu 1495 非常可乐(BFS)
- FZU
- C++11特性:智能指针介绍
- 搭建图片服务器
- MY FIRST BLOG ABOUT SOFTWARE PROGRAMMING
- servlet开发、访问步骤及错误分析
- 搜索练习10/hdu.edu.cn/problem1495 非常可乐,bfs+回溯
- IMP-00003:遇到ORACLE错误 27477,调度对象已存在
- UVA Meeting Room Arrangement
- selenium模拟点击下一页出现unknown error: Element is not clickable at point (80, 60)
- springMVC-注解开发(上)
- Spring 源码读书笔记
- 关于Segnet训练过程中的几个问题
- linux shell(一)
- Socket通信原理和实践