伫倚危楼风细细,望极春愁,黯黯生天际。草色烟光残照里,无言谁会凭阑意。

拟把疏狂图一醉,对酒当歌,强乐还无味。衣带渐宽终不悔,为伊消得人憔悴。——柳永

题目:倒水问题

网址:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=18&page=show_problem&problem=1544

There are three jugs with a volume of a, b and c liters. (a, b, and c are positive integers not greater

than 200). The first and the second jug are initially empty, while the third is completely filled with

water. It is allowed to pour water from one jug into another until either the first one is empty or the

second one is full. This operation can be performed zero, one or more times.

You are to write a program that computes the least total amount of water that needs to be poured;

so that at least one of the jugs contains exactly d liters of water (d is a positive integer not greater

than 200). If it is not possible to measure d liters this way your program should find a smaller amount

of water d

′ < d which is closest to d and for which d



liters could be produced. When d



is found, your

program should compute the least total amount of poured water needed to produce d



liters in at least

one of the jugs.

Input

The first line of input contains the number of test cases. In the next T lines, T test cases follow. Each

test case is given in one line of input containing four space separated integers — a, b, c and d.

Output

The output consists of two integers separated by a single space. The first integer equals the least total

amount (the sum of all waters you pour from one jug to another) of poured water. The second integer

equals d, if d liters of water could be produced by such transformations, or equals the closest smaller

value d



that your program has found.

Sample Input
2
2 3 4 2
96 97 199 62

Sample Output

2 2
9859 62

这道题可以使用优先队列BFS解决。

不难清楚,状态就是(a,b,c)代表三个容器中的当前水量(注意:顺序有差别)。

状态就是(a,b,c),直接跑一遍BFS即可。

核心在于,该状态记录起来过于繁琐,如何简化状态?

显然:总水量是定值,那么只要前两个容器水量确定,就可以刻画出了整个状态!所以状态数组仅需二维即可。该状态下需要判重。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std; const int maxn = 200 + 5;
struct node
{
int dist, cup[3];
bool operator < (const node& rhs) const
{
return dist > rhs.dist;
}
};
int cap[3], d, dis[maxn][maxn];
bool vis[maxn][maxn];
void bfs()
{
int ans = 0, num = 0x7f;
priority_queue <node> Q;
while(!Q.empty()) Q.pop();
if(cap[2] <= d)
{
printf("0 %d\n", cap[2]);
return;
}
memset(dis, 0x7f, sizeof(dis));
memset(vis, false, sizeof(vis));
node start;
start.dist = 0, start.cup[0] = 0, start.cup[1] = 0, start.cup[2] = cap[2];
Q.push(start);
dis[0][0] = 0;
vis[0][0] = true;
int v[3], count;
while(!Q.empty())
{
node now = Q.top(), next;
Q.pop();
v[0] = now.cup[0], v[1] = now.cup[1], v[2] = now.cup[2];
if(v[0] == d || v[1] == d || v[2] == d)
{
printf("%d %d\n", dis[now.cup[0]][now.cup[1]], d);
return;
}
for(int i = 0; i < 3; ++ i)
{
if(v[i] < d && ans < v[i])
{
ans = v[i];
num = now.dist;
}
if(v[i] == ans) num = min(num, now.dist);
} for(int i = 0; i < 3; ++ i)
{
if(now.cup[i])
for(int j = 0; j < 3; ++ j)
{
if(j != i)
{
if(now.cup[i] + now.cup[j] > cap[j]) count = cap[j] - now.cup[j];
else count = now.cup[i];
now.cup[i] -= count, now.cup[j] += count;
if(dis[now.cup[0]][now.cup[1]] - count >= dis[v[0]][v[1]])
{
dis[now.cup[0]][now.cup[1]] = dis[v[0]][v[1]] + count;
if(!vis[now.cup[0]][now.cup[1]])
{
vis[now.cup[0]][now.cup[1]] = true;
Q.push((node)
{
dis[now.cup[0]][now.cup[1]], now.cup[0], now.cup[1], now.cup[2]
});
}
}
now.cup[i] += count, now.cup[j] -= count;
}
}
}
}
printf("%d %d\n", num, ans);
return;
}
int main()
{
int T;
scanf("%d", &T);
while(T --)
{
for(int i = 0; i < 3; ++ i)
scanf("%d", &cap[i]);
scanf("%d", &d);
bfs();
}
return 0;
}

该道题启示我们可以发掘一些隐含的条件来简化状态,从而简化时间及空间的复杂度。

UVA10603 倒水问题 Fill的更多相关文章

  1. uva10603 倒水问题

    状态搜索.类似八数码问题 AC代码 #include<cstdio> #include<queue> #include<cstring> #include<a ...

  2. UVa10603 倒水 Fill-状态空间搜索

    https://vjudge.net/problem/UVA-10603 There are three jugs with a volume of a, b and c liters. (a, b, ...

  3. 关于BFS和dijkstra(2019.04.20)

    我的BFS板子 struct node{/*略*/};//表示一个状态 std::map<node,bool>vis;//判断每个状态是否已访问过 std::queue<node&g ...

  4. UVa10603 Fill

    解题思路:这是神奇的一题,一定要好好体会.见代码: #include<cstdio> #include<cstring> #include<algorithm> # ...

  5. 【UVA10603】Fill (构图+最短路)

    题目: Sample Input22 3 4 296 97 199 62Sample Output2 29859 62 题意: 有三个杯子它们的容量分别是a,b,c, 并且初始状态下第一个和第二个是空 ...

  6. 倒水问题(Fill, UVa 10603)

    [题目描述] 有三个没有刻度的水壶,容量分别为a,b和c(单位为升,都是<=200的正整数).初始时前两个水壶是空的,而第三个装满了水.每次可以从一个水壶往一个水壶里倒水,直到一个水壶倒空或者另 ...

  7. UVa 10603 Fill (BFS && 经典模拟倒水 && 隐式图)

    题意 : 有装满水的6升的杯子.空的3升杯子和1升杯子,3个杯子中都没有刻度.不使用道具情况下,是否可量出4升水呢? 你的任务是解决一般性的问题:设3个杯子的容量分别为a, b, c,最初只有第3个杯 ...

  8. 倒水问题(Fill,UVA 10603) lrj白书 p202

    看着lrj的代码自己敲了一遍,还没调试成功.... 有时间再进行完善 /* 状态start到各个状态u1,u2,u3..... 的倒水量分别为u1.dist,u2.dist,u3.dist.... * ...

  9. UVA-10603 Fill (BFS)

    题目大意:有三个已知体积但不知刻度的杯子,前两个杯子中初始时没有水,第三个装满水,问是否可以倒出d升水,如果倒不出,则倒出一个最大的d’,使得d’<=d,并且在这个过程中要求总倒水量最少. 题目 ...

随机推荐

  1. python学习第二节 数据类型、字符编码、文件处理

    标准数据类型 Python3 中有六个标准的数据类型: Number(数字) String(字符串) List(列表) Tuple(元组) Sets(集合) Dictionary(字典) 数字 #整型 ...

  2. 10年阿里自动化测试架构师帮您收集的:git常用命令大全以及git原理图【泣血推荐,建议收藏】

    一.Git分布式版本控制简介 ​ Git 是一个很强大的分布式版本控制系统.它不但适用于管理大型开源软件的源代码,管理私人的文档和源代码也有很多优势.本来想着只把最有用.最常用的 Git 命令记下来, ...

  3. 写给程序员的机器学习入门 (二) - pytorch 与矩阵计算入门

    pytorch 简介 pytorch 是目前世界上最流行的两个机器学习框架的其中之一,与 tensoflow 并峙双雄.它提供了很多方便的功能,例如根据损失自动微分计算应该怎样调整参数,提供了一系列的 ...

  4. vue中使用阿里图标库iconfont和在旧有的iconfont中添加新的图标

    第一步 下载样式http://www.iconfont.cn/选择图表,点击加入购物车 第二步 解压下载文件 第三步 修改文件名称 与 iconfont.css 名路径 第四步 将@font-face ...

  5. Jmeter 压力测试笔记(4)--分布式部署

    分布式部署:坑,大坑~ 超级坑~~~~ 在这里坑了2天,整整2天.其它略过不表下面只写经验: 在linux下,centos7系统   1主 14执行机. jmeter版本 5.2.1  所有机器在同一 ...

  6. Hadoop(五):HDFS的JAVA API基本操作

    HDFS的JAVA API操作 HDFS在生产应用中主要是客户端的开发,其核心步骤是从HDFS提供的api中构造一个HDFS的访问客户端对象,然后通过该客户端对象操作(增删改查)HDFS上的文件. 主 ...

  7. Gradle系列之初识Gradle

    原文首发于微信公众号:躬行之(jzman-blog) 学习 Android 有一段时间了,开发中经常使用到 Gradle ,但是不知道 Gradle 构建项目的原理,计划花一点时间学习一下 Gradl ...

  8. 萌新带你开车上p站(一)

    本文作者:萌新 0x01前言 这一系列文章为pwnable.krToddlr’s Bottle的全部题解,其中有三道题目相对而言稍难或者说比较经典,单独成篇,其他题目的题解放在一起发出来. 0x02f ...

  9. 30.4 Map HashMap

    本文将会讲解到: Map和Collection的对比 Map接口的使用,实现类HashMap的使用 /* * 需求:实现学号和姓名这样有对应关系的数据存储 * 为了体现这种有对应关系的数据,我们使用以 ...

  10. 22.4 Extends --super 和 this 的区别

    /* * this和super的区别 this:当前对象的引用 调用子类的成员变量 调用子类的成员方法 在子类的构造方法第一行调用子类其他构造方法 super:子类对象的父类引用 调用父类的成员变量 ...