Fill-倒水问题(Uva-10603-隐式图路径寻找问题)
原题:https://uva.onlinejudge.org/external/106/10603.pdf
有三个没有刻度的杯子,它们的容量分别是a, b, c, 最初只有c中的杯子装满水,其他的被子都是空的。问如果通过倒水得到d升水, 若可以得到,还要求最少的倒水总量(每倒一次水,都加入到总量里)。若不能得到d升水,求比d小的距离d最近的d'升水, 及最少倒水总量。
分析:
因为是求最少倒水总量,本能地想到用bfs搜索。最开始读错题了...看成求倒水的最少次数,这个很简单.....我们可以把求解的过程看成是空间状态的搜索,每一个状态都有一组a, b, c, pour_amount (分别对应三个杯子里的水量和到达当前状态需要的倒水总量)。如果把每个状态想象成一个结点, 整个搜索的过程就是图的遍历过程。
难点:
这道题的每一个状态有四个变量,所以要考虑所有四种变量的所有变化情况。方法是每次枚举当前a,b,c的下一个可达结点。这里有一个可以回溯剪枝的要点,就是结点判重,如果下一个结点的a,b,c曾经遍历过且它的pour_amount小于当前的pour_amount,回溯.结点判重的时候还有一个难点就是自己实现一个哈希表.对于一个状态a,b,c,对应一个到达这个状态的最小pour_amount
如果用stl自带的map,速度非常慢,比如1000组数据需要耗时4s左右
然而如果用自己实现的hash_map,1000组数据只要0.003s
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int MAXHASHSIZE = ;
int d, _head[MAXHASHSIZE], _next[MAXHASHSIZE];
int vol[], _d, ans, idx, st[MAXHASHSIZE], pour_set[MAXHASHSIZE]; struct Node {
int v[], pour;
Node(int a = , int b = , int c = , int p = ) {
v[] = a; v[] = b; v[] = c; pour = p;
}
bool operator == (const Node &rhs) const {
for (int i = ; i < ; i++) if (rhs.v[i] != v[i]) return false;
if (rhs.pour != pour) return false;
return true;
}
}; void init() {
_d = -;
ans = ;
idx = ;
memset(_head, , sizeof(_head));
} bool try_to_insert(Node &cur) {
int status = cur.v[] * + cur.v[] * + cur.v[];
int h = status % MAXHASHSIZE;
int u = _head[h];
while (u) {
if (st[u] == status) {
if (cur.pour < pour_set[u]) {
pour_set[u] = cur.pour;
return ;
}
return ;
}
u = _next[u];
}
st[idx] = status;
pour_set[idx] = cur.pour;
_next[idx] = _head[h];
_head[h] = idx++;
return ;
} void bfs(Node start) {
pour_set[] = start.pour;
try_to_insert(start);
queue<Node> q;
q.push(start);
while (!q.empty()) {
Node cur = q.front(); q.pop();
for (int i = ; i < ; i++) {
if (cur.v[i] == _d)
ans = min(ans, cur.pour);
else if (cur.v[i] > _d && cur.v[i] <= d) {
ans = cur.pour;
_d = cur.v[i];
}
if (cur.v[i] != )
for (int j = ; j < ; j++) if (i != j) {
int pour = min(cur.v[i], vol[j] - cur.v[j]);
cur.v[i] -= pour;
cur.v[j] += pour;
Node nextn = Node(cur.v[], cur.v[], cur.v[], cur.pour + pour);
cur.v[i] += pour;
cur.v[j] -= pour;
if (try_to_insert(nextn)) q.push(nextn);
}
}
}
} int main() {
int T;
scanf("%d", &T);
while (T--) {
init();
scanf("%d%d%d%d", &vol[], &vol[], &vol[], &d);
bfs(Node(, , vol[], ));
printf("%d %d\n", ans, _d);
}
return ;
}
Fill-倒水问题(Uva-10603-隐式图路径寻找问题)的更多相关文章
- 倒水问题UVA 10603——隐式图&&Dijkstra
题目 给你三个容量分别为 $a,b,c$ 的杯子,最初只有第3个杯子装满了水,其他两个杯子为空.最少需要到多少水才能让一个某个杯子中的水有 $d$ 升呢?如果无法做到恰好 $d$ 升,就让某个杯子里的 ...
- 倒水问题 (FillUVa 10603) 隐式图
题意:本题的题意是给你三个杯子,第一二个杯子是空的,第三个杯子装满水,要求是量出一定容量d升的水.若是得不到d升的水,那就让某一个杯子里面的水达到d',使得d'尽量接近d升. 解题思路:本题是给出初始 ...
- UVA 658 状态压缩+隐式图+优先队列dijstla
不可多得的好题目啊,我看了别人题解才做出来的,这种题目一看就会做的实在是大神啊,而且我看别人博客都看了好久才明白...还是对状态压缩不是很熟练,理解几个位运算用了好久时间.有些题目自己看着别人的题解做 ...
- 【UVA】658 - It's not a Bug, it's a Feature!(隐式图 + 位运算)
这题直接隐式图 + 位运算暴力搜出来的,2.5s险过,不是正法,做完这题做的最大收获就是学会了一些位运算的处理方式. 1.将s中二进制第k位变成0的处理方式: s = s & (~(1 < ...
- nyoj 21--三个水杯(隐式图bfs)
三个水杯 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识 ...
- 八数码问题+路径寻找问题+bfs(隐式图的判重操作)
Δ路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条凑够初始状态到终止问题的最优路径, 而不是像回溯法那样找到一个符合某些要求的解. 八数码问题就是路径查找问题背景下的经典训练题目. 程序框架 p ...
- uva658(最短路径+隐式图+状态压缩)
题目连接(vj):https://vjudge.net/problem/UVA-658 题意:补丁在修正 bug 时,有时也会引入新的 bug.假定有 n(n≤20)个潜在 bug 和 m(m≤100 ...
- UVA - 658 It's not a Bug, it's a Feature! (隐式图的最短路,位运算)
隐式的图搜索,存不下边,所以只有枚举转移就行了,因为bug的存在状态可以用二进制表示,转移的时候判断合法可以用位运算优化, 二进制pre[i][0]表示可以出现的bug,那么u&pre[i][ ...
- UVa 10603 Fill (BFS && 经典模拟倒水 && 隐式图)
题意 : 有装满水的6升的杯子.空的3升杯子和1升杯子,3个杯子中都没有刻度.不使用道具情况下,是否可量出4升水呢? 你的任务是解决一般性的问题:设3个杯子的容量分别为a, b, c,最初只有第3个杯 ...
随机推荐
- cas sso单点登录系列8_抛弃Https让Cas以Http协议提供单点登录服务
转:http://blog.csdn.net/ycyk_168/article/details/18668951 本文环境: 1.apache-tomcat-7.0.50-windows-x86 2. ...
- X-Plane数据交互
要用X-Plane进行二次开发,免不了需要进行参数的传递,下面我们来看看与X-Plane进行数据交互都有哪些方式. 与FSX和Flightgear基本一样,X-Plane支持插件,自然也支持通过插件进 ...
- Easyui的combobox组件无法选择内容
我切换combobox的内容的时候,老是选中的是第一行的数据,因为我渲染的时候没有给它valueField和textField的字段,而默认的又不是我要求的. 加上就好了. $("#tool ...
- php之购物车类思路及代码
<?php /* 购物车类 1.整站范围内,购物车--全局有效 解决:把购物车的信息,放在session里 2.既然全局有效,购物车的实例只有一个 解决:单例模式 技术选型:session+单例 ...
- jquery 自定义tab
<!DOCTYPE html> <html> <head> <script src="/jquery/jquery-1.11.1.min.js&qu ...
- 用urlencode(String str)对URL传递参数进行编码,提高安全
在PHP 提交地址后面带有参数的时候,参数会在浏览器的地址栏暴露无疑,这样是不安全的,这个时候就必须用些方法对这些参数进行安全处理 这里可以用 urlencode(String URL);//对URL ...
- jQuery height()、innerHeight()、outerHeight()函数的区别
参考: http://www.365mini.com/tech 函数 高度范围 jQuery版本 支持写操作 height() height 1.0+ 1.0+ innerHeight() heigh ...
- BZOJ 1032 祖玛
Description 这是一个流行在Jsoi的游戏,名称为祖玛.精致细腻的背景,外加神秘的印加音乐衬托,彷佛置身在古老的国度里面,进行一个神秘的游戏——这就是著名的祖玛游戏.祖玛游戏的主角是一只石青 ...
- [BZOJ 1084] [SCOI2005] 最大子矩阵 【DP】
题目链接:BZOJ - 1084 题目分析 我看的是神犇BLADEVIL的题解. 1)对于 m = 1 的情况, 首先可能不取 Map[i][1],先 f[i][k] = f[i - 1][k]; ...
- 人在江湖飘,哪能不挨刀。CENTOS之后,UBUNTU,FEDORA都要安装起来作测试啊
还好,我们有VIRTUAL BOX.