题目:

给出三个杯子(没有刻度线)的容量,起初之后第三个杯子是满的,其他的两个杯子是空的,容量分别是a、b、c。问最少需要倒多少升水才能让某一个杯子中的水有d升?如果不能恰好做到d升,就让某一个杯子里的水是D升,其中D<d并且尽量接近d。(1≤a,b,c,d≤200)。要求输出最少的倒水量和目标水量d或D。

思路:

菜是原罪,需要赎罪啊!!

1.一看到这种求最小值的问题很应该想到是用BFS了。

2.BFS需要标记状态呀,那201*201*201=8120601这内存有些吃不消啊,那前两个杯子的水固定了,总的水量又是不变的,那只用前两个杯子的

水量就可以标记所有可能的状态了。这样就把状态缩小到201*201了。

3.Node结构体中保存的是一个状态,“状态”这个词很玄乎啊,有到当前状态已经倒过的水量dist和三个杯子中还有的水量v[0]、v[1]、v[2]。

4.紫书的代码写的优美啊!!值的好好的学习!!

代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1000000009
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
const int maxn = ;
struct Node{
int v[],dist;//dist保存的是到当前状态已经倒过的最小水量
bool operator<(const Node& rhs)const{
return dist>rhs.dist;
}
};
int vis[maxn][maxn],cap[],ans[maxn]; void update_ans(const Node& u){//更新答案
for(int i=; i<; i++){
int d=u.v[i];
if(ans[d]< || u.dist<ans[d])
ans[d] = u.dist;
}
} void solve(int a,int b,int c,int d){
cap[]=a;cap[]=b;cap[]=c;//记录目标状态的水量是多少
memset(vis,,sizeof(vis));//清空所有的可能出现的状态
memset(ans,-,sizeof(ans));//清空答案数组
priority_queue<Node>q; Node start;//初始状态,按照题目要求赋值
start.dist = ;
start.v[] = start.v[] = ;
start.v[] = c;
q.push(start);
vis[][] = ;//标记a、b杯子为空的状态
while(!q.empty()){
Node u = q.top();q.pop();
update_ans(u);
if(ans[d]>=) break;//如果已经找到的答案就break
for(int i=; i<; i++){//i表示的是倒出水的杯子
for(int j=; j<; j++){//j表示的是被倒出水的杯子
if(i!=j){//自己不能给自己倒水
if(u.v[i]== || u.v[j]==cap[j])continue;//如果倒出水的杯子里没有水
//被倒的杯子已经满了,就进行下一个状态
int amount = min(cap[j], u.v[i]+u.v[j])-u.v[j];//重点了!!
/*
要倒一定是全部倒出来,所以j杯子被倒水之后有两种状态
1.倒之后满了
2.倒之后没有满
从这两种状态中取一个最小的水量记录下来
*/
Node u2;//赋值一个新的状态
memcpy(&u2, &u, sizeof(u));
u2.dist = u.dist+amount;
u2.v[i] -= amount;
u2.v[j] += amount;
if(!vis[u2.v[]][u2.v[]]){//如果这个状态没有出现过,就标记一下入队列
vis[u2.v[]][u2.v[]] = ;
q.push(u2);
}
}
}
}
}
while(d>=){//遍历答案并输出
if(ans[d] >= ){
printf("%d %d\n",ans[d],d);
return;
}
d--;
}
} int main(){
int T,a,b,c,d;
scanf("%d",&T);
while(T--){
scanf("%d%d%d%d",&a,&b,&c,&d);
solve(a,b,c,d);
}
return ;
}

UVA - 10603 Fill(BFS求最小值问题)的更多相关文章

  1. UVA 10603 - Fill BFS~

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&c ...

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

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

  3. UVa 10603 Fill [暴力枚举、路径搜索]

    10603 Fill There are three jugs with a volume of a, b and c liters. (a, b, and c are positive intege ...

  4. UVa 10603 Fill (暴力BFS+优先队列)

    题意:给定4个数,a,b,c,d,分别代表空杯子容积为a,b,一个盛满水的杯子容积为c,让你不断倒水,找一个dd,是不是存在某个时刻, 某个杯子里的水dd,和d相同,或者无限接近.让求最少的倒水量和d ...

  5. UVA 10603 Fill(正确代码尽管非常搓,网上很多代码都不能AC)

    题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=1544">click here~ ...

  6. UVA - 10603 Fill(隐式图搜索)

    题目大意:经典的倒水问题. 给你三个瓶子,体积为a,b,c. 刚開始a.b是空的,c是满的,如今要求你到出体积为d的水.倒水的规则为,要么倒水方为空,要么接水方满 问倒到容量为d时,倒水的最小体积是多 ...

  7. UVA 10603 Fill

    题意: 题目的意思是倒水,给出的四个数据是第一个水杯,第二个水杯,第三个水杯,和目标水量.一开始只有第三个水杯是满的,剩下的水杯是空的.倒水的时候只能把倒水出来的这个杯子倒空,或是倒水进去的杯子倒满. ...

  8. 【路径寻找问题】UVa 10603 - Fill

    如家大神书上的例题.第一次接触也是按代码敲得.敲的过程感觉很直观.但自己写估计会写的乱七八糟.以后不能砍得难就不愿意做这种题.否则只能做一些水题了.(PS:48) 紫书 #include<ios ...

  9. 图-用DFS求连通块- UVa 1103和用BFS求最短路-UVa816。

    这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者 ...

随机推荐

  1. windows console Kill PID 端口查看

    开始--运行--cmd 进入命令提示符 输入netstat -ano 即可看到所有连接的PID 之后在任务管理器中找到这个PID所对应的程序如果任务管理器中没有PID这一项,可以在任务管理器中选&qu ...

  2. 转 source insight 复制后光标在前面

    source insight 里编辑的时候,每次粘贴后,光标停留在粘贴内容的前面. 我想把它设定为 粘贴后,光标移动倒粘贴内容的后面. 怎么做? 这是个设置问题,按照下面的步骤设定就可以了. Opti ...

  3. Dinic(模板 再错是不可能的 这辈子都不可能了)

    #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #inclu ...

  4. werkzeug 详解

    首先,先向大家介绍一下什么是 werkzeug,Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库.这里稍微说一下, werkzeug 不是一个web服务器,也不是一个web框架, ...

  5. 4. extjs中form中的frame:true表示什么

    转自:https://blog.csdn.net/qiu512300471/article/details/23737217 设置为true时可以为panel添加背景色.圆角边框等,如下图 下面的是f ...

  6. 如何截取iframe的内容,修改他的CSS

    function   setv(){        $("#innerContent").contents().find(".listTable-01").cs ...

  7. bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级【分层图+spfa】

    至死不用dijskstra系列2333,洛谷上T了一个点,开了O2才过 基本想法是建立分层图,就是建k+1层原图,然后相邻两层之间把原图的边在上一层的起点与下一层的终点连起来,边权为0,表示免了这条边 ...

  8. 思维/构造 HDOJ 5353 Average

    题目传送门 /* 思维/构造:赛后补的,当时觉得3题可以交差了,没想到这题也是可以做的.一看到这题就想到了UVA_11300(求最小交换数) 这题是简化版,只要判断行不行和行的方案就可以了,做法是枚举 ...

  9. 三分 POJ 2420 A Star not a Tree?

    题目传送门 /* 题意:求费马点 三分:对x轴和y轴求极值,使到每个点的距离和最小 */ #include <cstdio> #include <algorithm> #inc ...

  10. UE编辑器编译和运行java设置

    工具原料: UE编辑器 1点击“高级”,再点击“工具配置”. 2点击“插入”,在“菜单项”名称上输入“编译java程序”,在“命令行”里输入“javac %n%e”,在工作目录上填“%p”. 3切换到 ...