HDU1495-非常可乐-BFS
2015-08-31 20:16
399 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1495
题意:三个瓶子,容量为s,a,b,且s装满饮料 s=a+b
求至少倒多少下能使得某两个瓶子装着相同多的饮料。这是个模拟搜索BFS。想清楚总共就只有六种操作就行了。
题意:三个瓶子,容量为s,a,b,且s装满饮料 s=a+b
求至少倒多少下能使得某两个瓶子装着相同多的饮料。这是个模拟搜索BFS。想清楚总共就只有六种操作就行了。
#include<iostream> #include<string> #include<cstdio> #include<cstring> #include<map> #include<queue> #include<cmath> #include<stack> #include<set> #include<vector> #include<algorithm> #define LL long long #define inf 1<<29 #define s(a) scanf("%d",&a) #define CL(a,b) memset(a,b,sizeof(a)) using namespace std; const int N=105; int n,s,a,b,c; struct node{int dp[3],step;}; bool vis ; queue<node>q; void flag(node &f) { f.step++; q.push(f); vis[f.dp[0]][f.dp[1]][f.dp[2]]=true; } int bfs(int s,int a,int b) { CL(vis,false); while(!q.empty()) q.pop(); node f,f_tmp; f.step=0; f.dp[0]=s; f.dp[1]=0; f.dp[2]=0; q.push(f); while(!q.empty()){ f=q.front();q.pop(); if(f.dp[0]==s/2&&(f.dp[1]==s/2||f.dp[2]==s/2)) return f.step; if(f.dp[1]==s/2&&f.dp[2]==s/2) return f.step; f_tmp=f; // 第一种操作方法,1->2 if(f.dp[0]>0&&f.dp[1]<a){ if(f.dp[0]>=(a-f.dp[1])){ f.dp[0]-=(a-f.dp[1]); f.dp[1]=a; }else{ f.dp[1]+=f.dp[0]; f.dp[0]=0; } if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f); } f=f_tmp; // 第二种操作方法,1->3 if(f.dp[0]>0&&f.dp[2]<b){ if(f.dp[0]>=(b-f.dp[2])){ f.dp[0]-=(b-f.dp[2]); f.dp[2]=b; }else{ f.dp[2]+=f.dp[0]; f.dp[0]=0; } if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f); } f=f_tmp; // 第三种操作方法,2->1 if(f.dp[1]>0&&f.dp[0]<s){ if(f.dp[1]>=(s-f.dp[0])){ f.dp[1]-=(s-f.dp[0]); f.dp[0]=s; }else{ f.dp[0]+=f.dp[1]; f.dp[1]=0; } if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f); } f=f_tmp; // 第四种操作方法,2->3 if(f.dp[1]>0&&f.dp[2]<b){ if(f.dp[1]>=(b-f.dp[2])){ f.dp[1]-=(b-f.dp[2]); f.dp[2]=b; }else{ f.dp[2]+=f.dp[1]; f.dp[1]=0; } if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f); } f=f_tmp; // 第五种操作方法,3->1 if(f.dp[2]>0&&f.dp[0]<s){ if(f.dp[2]>=(s-f.dp[0])){ f.dp[2]-=(s-f.dp[0]); f.dp[0]=s; }else{ f.dp[0]+=f.dp[2]; f.dp[2]=0; } if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f); } f=f_tmp; // 第六种操作方法,3->2 if(f.dp[2]>0&&f.dp[1]<a){ if(f.dp[2]>=(a-f.dp[1])){ f.dp[2]-=(a-f.dp[1]); f.dp[1]=a; }else{ f.dp[1]+=f.dp[2]; f.dp[2]=0; } if(!vis[f.dp[0]][f.dp[1]][f.dp[2]]) flag(f); } } return -1; } int main() { while(~scanf("%d%d%d",&s,&a,&b)){ if(!s&&!a&&!b) break; if(s&1) printf("NO\n"); else{ int k=bfs(s,a,b); if(k==-1) printf("NO\n"); else printf("%d\n",k); } } return 0; }
相关文章推荐
- UITextFielddelegate委托方法注释
- hdu4770 状态压缩+枚举
- LeetCode(47)Permutations II
- Java技术积累——用最原始的代码见证分页查询实现原理
- hust1350Trie【字典树+dfs || 字典树 + LCA】
- LeetCode(47)Permutations II
- Linux编程基础
- Servlet中用于会话跟踪的三种机制
- HDU3722 Card Game(KM最小费用圈覆盖)
- 黄聪:WordPress动作钩子函数add_action()、do_action()源码解析
- linux 文件系统解析及相关命令
- 计算1到100的整数和
- hdu 2899 Strange fuction
- zoj 1516 Uncle Tom's Inherited Land(二分匹配·链式前向星)
- POJ3268 Silver Cow Party(dijkstra)
- ios开发进阶之网络06 网络安全 UIWebView
- 二分查找算法
- 省市选择器
- 面试题:最长公共前缀
- 简述Error和Exception的区别