HDU1495 非常可乐
2015-10-12 19:03
330 查看
解题思路:简单的宽搜,见代码:
View Code
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int maxn = 105; int S, n, m, cap[3], vis[maxn][maxn]; struct node{ int v[3];//每个子装的水 int cnt; //倒水的次数 bool friend operator < (node A, node B){ return A.cnt > B.cnt; //cnt越小,优先级越高 } }s, e; priority_queue<node> q; //优先队列 int bfs() { while(!q.empty()) q.pop(); q.push(s); while(!q.empty()) { s = q.top(); q.pop(); // printf("s.cnt = %d\n", s.cnt); //太大意,因为这行没注释,WA了一发 //n杯子和s杯子各有一半可乐时返回倒水次数 if(s.v[0] == S / 2 && s.v[2] == S / 2) return s.cnt; //i杯子往j杯子里面倒水 for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++) { if(i == j) continue; //不能往自己的杯子倒水 //如果i杯子是空的或者j杯子已满,则不用倒水 if(s.v[i] == 0 || s.v[j] == cap[j]) continue; int t = min(s.v[i], cap[j] - s.v[j]); //自己思考这一步 e = s; //这步不能忘了 e.v[i] = s.v[i] - t, e.v[j] = s.v[j] + t, e.cnt = s.cnt + 1; if(!vis[e.v[0]][e.v[1]]) //没访问过 { vis[e.v[0]][e.v[1]] = 1; //标记为已经访问 q.push(e); } } } return -1; //若没有符合条件的,则返回-1 } int main() { while(~scanf("%d %d %d", &S, &n, &m) && (S || n || m)) { if(S % 2) //s为奇数,则不可能均分 { printf("NO\n"); continue; } if(n == m) //n等于m时,直接把一个杯子倒满即可 { printf("1\n"); continue; } int tmp; //初始化n为更大的杯子 if(m > n) tmp = n, n = m, m = tmp; memset(vis, 0, sizeof(vis)); cap[0] = n, cap[1] = m, cap[2] = S; s.v[0] = 0, s.v[1] = 0, s.v[2] = S, s.cnt = 0; vis[0][0] = 1; int ans = bfs(); if(ans == -1) printf("NO\n"); else printf("%d\n", ans); } return 0; }
View Code
相关文章推荐
- 关于setpeer和getpeer的作用
- android:Kotlin Java Kotlin android Kotlin
- centos 笔记
- 【转】吴晓波:马化腾的“邮件癖”
- Codeforces 11D A Simple Task 统计简单无向图中环的个数
- 跟我一起用windows快捷键(持续更新)
- zepto的tap事件的点透问题的几种解决方案
- PDA简单打包
- 老师oracle讲义第五天
- ios实现截屏(转)
- UILabel 使用解析
- RAID4 慢的原因
- 监控火车票余票
- 什么是影响日活/月活的因素?先天决定论vs.后天培养论
- 正则表达式 Java
- java静态内部类
- 我在北京工作,但是户口在重庆。 今天妈妈去办理她的医保,办理的人户口本上的人都要办医保卡,我在北京已经有了医保了。重庆那边就需要我出示这边单位的证明,请问我应该如何去开呢?
- oracle学习第五天
- Java基础知识强化之网络编程笔记10:TCP之客户端读取文本文件服务器控制台输出
- 程序员参考资料汇总_伊甸干果园