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

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

题目:倒水问题

网址: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. 还不懂 ConcurrentHashMap ?这份源码分析了解一下

    上一篇文章介绍了 HashMap 源码,反响不错,也有很多同学发表了自己的观点,这次又来了,这次是 ConcurrentHashMap 了,作为线程安全的HashMap ,它的使用频率也是很高.那么它 ...

  2. My背包九讲——01背包

    文章目录 背包问题中的常用变量说明 题目 解题思路 我想要想理解最简单 01背包就是要`理解

  3. 1047 Student List for Course (25分)

    Zhejiang University has 40,000 students and provides 2,500 courses. Now given the registered course ...

  4. Nginx知多少系列之(三)配置文件详解

    目录 1.前言 2.安装 3.配置文件详解 4.Linux下托管.NET Core项目 5.Linux下.NET Core项目负载均衡 6.Linux下.NET Core项目Nginx+Keepali ...

  5. ensp的基础路由命令,接口,下一跳的配置,入门必备

    关于ensp入门事情,第一件事当是安装必备三件套:而后,应该是接触路由和PC机了,最烦人满屏代码,眼花缭乱: 今天写一篇零基础接触ensp的首次操作,PC-路由-路由-PC的互通实验: 实验要拉出两台 ...

  6. "三号标题"组件:<h3> —— 快应用组件库H-UI

     <import name="h3" src="../Common/ui/h-ui/text/c_h3"></import> < ...

  7. 登陆ECP后,无法正常现实OU

    当我们在ECP创建邮箱账户或者会议室的时候,发现无法预览所有OU信息 这是因为,默认情况下,Exchange只能识别到500个OU,如果要解决这个问题就需要我们到后端服务器修改配置文件 文件路径:C: ...

  8. 通过Java HTTP连接将网络图片下载到本地

    通过Java HTTP连接将网络图片下载到本地   只知道浏览器使用的是HTTP协议,那么如何将网络资源使用JavaHTTP下载下来呢! 这只是一个非常简单的小示例,只是不想每次碰到关于此方面的内容忘 ...

  9. java异常处理:finally中不要return

    java异常处理:finally中不要return 复制代码 public class Ex1 { public static void main(String[] args) { System.ou ...

  10. 数据结构和算法(Golang实现)(11)常见数据结构-前言

    常见数据结构及算法 数据结构主要用来组织数据,也作为数据的容器,载体. 各种各样的算法,都需要使用一定的数据结构来组织数据. 常见的典型数据结构有: 链表 栈和队列 树 图 上述可以延伸出各种各样的术 ...