UVA - 10603 Fill(BFS求最小值问题)
题目:
给出三个杯子(没有刻度线)的容量,起初之后第三个杯子是满的,其他的两个杯子是空的,容量分别是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求最小值问题)的更多相关文章
- UVA 10603 - Fill BFS~
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&c ...
- UVa 10603 Fill (BFS && 经典模拟倒水 && 隐式图)
题意 : 有装满水的6升的杯子.空的3升杯子和1升杯子,3个杯子中都没有刻度.不使用道具情况下,是否可量出4升水呢? 你的任务是解决一般性的问题:设3个杯子的容量分别为a, b, c,最初只有第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 ...
- UVa 10603 Fill (暴力BFS+优先队列)
题意:给定4个数,a,b,c,d,分别代表空杯子容积为a,b,一个盛满水的杯子容积为c,让你不断倒水,找一个dd,是不是存在某个时刻, 某个杯子里的水dd,和d相同,或者无限接近.让求最少的倒水量和d ...
- UVA 10603 Fill(正确代码尽管非常搓,网上很多代码都不能AC)
题目链接:option=com_onlinejudge&Itemid=8&page=show_problem&problem=1544">click here~ ...
- UVA - 10603 Fill(隐式图搜索)
题目大意:经典的倒水问题. 给你三个瓶子,体积为a,b,c. 刚開始a.b是空的,c是满的,如今要求你到出体积为d的水.倒水的规则为,要么倒水方为空,要么接水方满 问倒到容量为d时,倒水的最小体积是多 ...
- UVA 10603 Fill
题意: 题目的意思是倒水,给出的四个数据是第一个水杯,第二个水杯,第三个水杯,和目标水量.一开始只有第三个水杯是满的,剩下的水杯是空的.倒水的时候只能把倒水出来的这个杯子倒空,或是倒水进去的杯子倒满. ...
- 【路径寻找问题】UVa 10603 - Fill
如家大神书上的例题.第一次接触也是按代码敲得.敲的过程感觉很直观.但自己写估计会写的乱七八糟.以后不能砍得难就不愿意做这种题.否则只能做一些水题了.(PS:48) 紫书 #include<ios ...
- 图-用DFS求连通块- UVa 1103和用BFS求最短路-UVa816。
这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者 ...
随机推荐
- go10---struct
package main import ( "fmt" ) type test struct{} //空的结构体 type person struct { name string ...
- 扩展欧几里得模板&逆元求法
拓展欧几里得: 当 gcd ( a , b )= d 时,求绝对值和最小的 x , y 使得 x * a + y * b = d : d = gcd ( a , b ) = gcd ( b , a m ...
- IDEA 的使用(快捷键、括号对齐的方式)
Java IDE 工具不是只有一个 Eclipse,还有同样十分优秀的 IDEA. 0. 常用快捷键 查看与设置:[File]⇒ [Settings]⇒ [Keymap] back/forward:c ...
- [Codeforces 1058E] Vasya and Good Sequences
[题目链接] https://codeforces.com/contest/1058/problem/E [算法] 显然 , 我们只需考虑序列中每个数的二进制表示下1的个数即可. 不妨令Ai表示第i个 ...
- python cmd 启动python项目报错:no module named “xxx”
场景:使用pycharm编辑器启动pyhon项目时可以启动,但使用cmd启动时,会报:no module named “xxx”的错误,此时,有两种情况: 1.no module named “xxx ...
- SpringBoot中使用spring-data-jpa 数据库操作(上)
Java客户端使用Spring-Data-Jpa这个组件. Spring-Data-Jpa就是Spring对Hibernate的一个整合. 选择create在运行的时候它会自动帮我们创建一个表. sp ...
- apache相关补充
apache相关补充 sendfile机制 1)不用sendfile的传统网络传输过程: read(file, tmp_buf, len) write(socket, tmp_buf, len) 2) ...
- CodeForces 731B Coupons and Discounts (水题模拟)
题意:有n个队参加CCPC,然后有两种优惠方式,一种是一天买再次,一种是买两天,现在让你判断能不能找到一种方式,使得优惠不剩余. 析:直接模拟,如果本次是奇数,那么就得用第二种,作一个标记,再去计算下 ...
- 【计蒜客习题】两仪剑法(gcd)
两仪剑法是武当派武功的高级功夫,且必须 2 个人配合使用威力才大.同时该剑法招数变化太快.太多.设武当弟子甲招数变化周期为 n,武当弟子乙招数变化周期为 m,两弟子同时使用该剑法,当 2 人恰好同时达 ...
- es6之iterator,for...of
遍历器(Iterator)是一种统一的接口机制,来处理所有不同的数据结构. JavaScript 原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和 ...