UVA - 10603 Fill(隐式图搜索)

题目大意:经典的倒水问题。给你三个瓶子,体积为a,b,c。

刚开始a,b是空的,c是满的,现在要求你到出体积为d的水。倒水的规则为,要么倒水方为空,要么接水方满

问倒到容量为d时,倒水的最小体积是多少,如果不能倒出体积为d的水,找出d’ < d,最接近d的d’和最小的体积

解题思路:刚才时以为直接bfs,用vis标记一下就结束了,结果WA了。为什么会WA,因为我这样求的是倒水次数最少的,而不是倒水体积最小的,WA是肯定的了

接着将vis数组改成int型的,纪录达到这个状态时倒水的体积,结果可想而之TLE(可能是我写搓了。。)

借鉴了一下别人的,恍然大悟,用一个数组代表倒出这个体积的水时倒的水的最小体积,这样就可以减少很多种情况了,确实是一个大剪枝

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

#define N 210
#define INF 0x3f3f3f3f

struct Node{
    int have[3];
    int d;
}n1, n2;

int done[N], val[3];
int d;
bool vis[N][N];

void init() {
    memset(vis, 0, sizeof(vis));
    memset(done, 0x3f, sizeof(done));
    scanf("%d%d%d%d", &val[0], &val[1], &val[2], &d);
    done[0] = done[val[2]] = 0;
}

void bfs() {
    queue<Node> Q;
    vis[0][0] = true;
    n1.have[0] = n1.have[1] = n1.d = 0;
    n1.have[2] = val[2];
    Q.push(n1);

    while (!Q.empty()) {
        n1 = Q.front();
        Q.pop();

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++) {
                if (i ^ j) {
                    n2 = n1;
                    int tmp = val[j] - n2.have[j] < n2.have[i] ? val[j] - n2.have[j] : n2.have[i];
                    n2.have[j] += tmp;
                    n2.have[i] -= tmp;
                    n2.d += tmp;

                    if (!vis[n2.have[0]][n2.have[1]] || done[n2.have[0]] > n2.d || done[n2.have[1]] > n2.d || done[n2.have[2]] > n2.d) {
                        vis[n2.have[0]][n2.have[1]] = true;
                        for (int k = 0; k < 3; k++) {
                            done[n2.have[k]] = min(done[n2.have[k]], n2.d);
                        }
                        Q.push(n2);
                    }
                }
            }
    }
}

void solve() {
    bfs();
    for (int i = d; i >= 0; i--)
        if (done[i] != INF) {
            printf("%d %d\n", done[i], i);
            break;
        }
}
int main() {
    int test;
    scanf("%d", &test);
    while (test--) {
        init();
        solve();
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-28 16:32:23

UVA - 10603 Fill(隐式图搜索)的相关文章

UVa 658 - It&#39;s not a Bug, it&#39;s a Feature!(Dijkstra + 隐式图搜索)

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=599 题意: 补丁在修正bug时,有时也会引入新的bug.假定有n(n≤20)个潜在bug和m(m≤100)个补丁,每个补丁用两个长度为n的字符串表示,其中字符串的每个位置表示一个bug.第一个串表示打补丁之前的状态("-"表示该bug必须不存在,"+&

UVa10603 Fill (隐式图搜索+Dijkstra)

链接:http://acm.hust.edu.cn/vjudge/problem/19527分析:隐式图搜索,从初始状态(0,0,c)开始,维护一个到达k升水所需的最少倒水量ans.结点状态设计为v[3]表示当前状态三个杯子中的水量和到达此状态的倒水量.用一个二维vis判重,因为只要第1,2个杯子里的水量确定第3个杯子里的水量也就确定了,所以二维就足以表示了.然后跑一边Dijkstra,用优先队列每次取出倒水量最少的的结点进行扩展,然后用到了一个定序的技巧,规定从i号杯子倒到j号杯子里,生成一个

UVA 10603 Fill(正确代码虽然很搓,网上许多代码都不能AC)

在做用户查找时 因为要把查找的结果动态加载和显示,所以,那些html元素要由Ajax动态生成.用户打开查找界面时,有系统推荐的用户,而当用户按条件查找后,查找的结果动态加载和显示.所以考虑到用js来搞. 这个for循环就是移除已有的表单.然后根据Ajax请求过来的数据,动态生成新的表单对象.一定要注意j变量从大往小循环,否则,删除div元素后会引起serchResultLenth=serchResult.children.length;长度的变化(这个问题摸索了好久,才搞定,切记) for(va

uva 10603 Fill (BFS)

uva 10603 Fill 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

UVa658 It&#39;s not a Bug, it&#39;s a Feature! (最短路,隐式图搜索)

链接:http://vjudge.net/problem/UVA-658 分析:Dijkstra求隐式图最短路. 1 #include <cstdio> 2 #include <queue> 3 using namespace std; 4 5 const int maxn = 20; 6 const int maxm = 100 + 5; 7 const int INF = 1000000000; 8 9 int n, m, t[maxm], vis[1 << max

HDU5012Dice(隐式图搜索)

题目:HDU5012Dice(隐式图搜索) 题目大意:给你一个两个色子,规定每个面的序号,现在给你这两个色子的每个面的颜色(a1,a2,a3,a4,a5,a5)(b1,b2,b3,b4,b5,b6).现在要求比通过下面的四种旋转使得a序列和b序列一样.可以的话输出最少的旋转步数,不能输出-1. 解题思路:bfs + map判重.就是四种旋转的状态要弄清楚. 代码: #include <cstdio> #include <cstring> #include <map> u

zoj 3814 Sawtooth Puzzle(隐式图搜索)

题目链接:zoj 3814 Sawtooth Puzzle 题目大意:给定一个9宫拼图,每次可以挑选一个位置顺时针旋转,和普通拼图不一样的是每块拼图周围可能有齿转动一个可能导致全部拼图转变. 解题思路:隐式图搜索,9块拼图最多49个状态,对于每个状态枚举转动的位置,考虑转动的状态.一开始转移是用bfs写的,但是由于频繁申请队列,然后时间爆了 #include <cstdio> #include <cstring> #include <queue> #include &l

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

10603 Fill 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 rst and the second jug are initially empty, while the third is completely lled with water. It is allowed to pour water f

状态转移的最短路 隐式图搜索 UVA 658

紫书365 题目大意:给你n个全都是bug的东西,然后每次可以修复,给你修复前后的状态,问最后如果能把bug全都修复,最少需要多少时间. 思路:从最初状态开始,然后枚举bug即可. 表示priority里面的bool operator和单纯的sort的定义的大小于号是不一样的啊,如果你想用sort来计算struct从小到大的的话是这样的 struct Node{ int bugs, dist; bool operator < (const Node &a) const{ return dis