UVA 10603 Fill倒水问题
来源:互联网 发布:淘宝网帽子 编辑:程序博客网 时间:2024/06/05 19:02
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
题意:告诉三个杯子,总容量分别是a,b,c,最初只有C装满了,其他都为空,杯子没有刻度,只能互相倒水,问最终能否使得某个杯子有d单位的水,如果无法到达d,那就判断能到达的第一个小于d的单位能否到达,输出最小的倒水总量。
思路:把状态想想成结点,每次扩展取出水量最小的节点,然后各种转移。
#include <iostream>#include <stdio.h>#include <string>#include <cstring>#include <algorithm>#include <cmath>#include <queue>using namespace std;int cap[3];int vis[250][250];int ans[250];struct Node{ int v[3],dis; bool operator < (const Node& rhs) const { return rhs.dis<dis; }}f,t;void check(const Node& u){ for(int i=0;i<3;i++) { int a=u.v[i]; if(ans[a]<0 || u.dis<ans[a]) ans[a]=u.dis; }}void solve(int a,int b,int c,int d){ cap[0]=a;cap[1]=b;cap[2]=c; memset(ans,-1,sizeof ans); memset(vis,0,sizeof vis); priority_queue<Node>pq; vis[0][0]=1; f.dis=0; f.v[0]=0; f.v[1]=0; f.v[2]=c; pq.push(f); while(!pq.empty()) { f=pq.top(); pq.pop(); check(f); if(ans[d]>=0) break; for(int i=0;i<3;i++) for(int j=0;j<3;j++) { if(i==j)continue; if( f.v[i]==0 || f.v[j]==cap[j] ) continue; int tmp=min(cap[j],f.v[i]+f.v[j])-f.v[j]; t=f;//只是对三个部分中的两个进行了操作,第三个 部分要直接赋值过去 t.dis=f.dis+tmp; t.v[i]=f.v[i]-tmp; t.v[j]=f.v[j]+tmp; if(!vis[t.v[0]][t.v[1]]) { vis[t.v[0]][t.v[1]]=1; pq.push(t); } } } while(d>=0) { if(ans[d]>=0) { printf("%d %d\n",ans[d],d); return; } d--; }}int main(){ int a,b,c,d; int T; scanf("%d",&T); { while(T--) { scanf("%d%d%d%d",&a,&b,&c,&d); solve(a,b,c,d); } } return 0;}
- UVA 10603 Fill倒水问题
- 倒水问题(Fill,UVa 10603)
- 倒水问题(Fill,UVa 10603)
- uva 10603 Fill(倒水问题 BFS)
- Fill (Uva 10603 bfs 倒水问题)
- UVA 10603 Fill(倒水问题)
- UVa 10603 - Fill,经典倒水问题+隐式图搜索+dfs
- 例题7-8 UVA 10603 Fill 倒水问题
- UVA 10603 Fill(状态空间搜索,倒水问题)
- UVA-10603 Fill 倒水问题 BFS+优先队列
- 例题7-8 倒水问题(Fill, UVa 10603)
- 10603 - Fill,倒水问题 bfs解
- uva 10603 倒水问题
- [隐式图搜索]Fill(倒水问题) UVA10603
- Uva 倒水问题
- uva 10603(Fill, 隐式图搜索问题)
- uva 10603 倒水 bfs
- UVa 10603 倒水
- Android ListView拉到顶/底部,像橡皮筋一样弹性回弹复位
- mysql中单双引号的特殊使用 以及mysql常见的转移字符
- python基础学习笔记<函数式编程与模块>
- 最大公约数
- 南邮 OJ 1537 G ? Area of Polycubes
- UVA 10603 Fill倒水问题
- UI0805_Page
- C++中的多态
- Java基础针对自己薄弱环节总结04(面向对象多态)
- 测试测试
- Android fragment中如何对listview添加监听事件
- 阿里航旅事业部的前端开发面试题
- 南邮 OJ 1542 GCC
- SQL Server 清理数据库日志文件