码迷,mamicode.com
首页 > 其他好文 > 详细

UVA10603 Fill

时间:2016-08-18 23:29:13      阅读:462      评论:0      收藏:0      [点我收藏+]

标签:

优秀的程序员一定是CV大师。能CV则CV的做法,可以省去许多编码和测试的时间。但是,如果出现小错误的话,找起来一样的费时

问题链接UVA10603 Fill

题意简述:有三个壶,容量分别是a、b和c升,开始时候第1个和第2个壶是空的,第3个壶是满水的。可以把一个壶的水倒入另一个壶中,直到倒空或将另外一个壶倒满。输入a、b、c和d,计算最少的倒水量,使得其中一个壶里有d升水。如果不能倒出d升水的话,那么找一个最大的d‘<d。输出倒水量和d,如果找不到的话输出倒水量和d‘。

问题分析将<a,b,c>看成是状态,进行状态展开搜索。开始的时候,所有水在c中,2个a和b都空着。过程中,可以将任何1个中的水倒到另外某个中,或将目标倒满,或将源倒空。因为没有刻度,只能这样。这个过程中,如果出现某个的水量等于d就找到解了。同时,也要考虑得不到d的情况,所以过程中需要将最大的d‘<d记录下来。容器间水倒来倒去,每次有6种倒法,对这6种倒法进行试探即可。求的是倒水量最小,所以用分支限界法实现,倒水量最小的状态优先展开

程序说明搜索过的状态就不需要再搜索了,用数组notvist[][][]来标记搜索过的状态。

这个问题的程序是先CV来的,然后做了适当的修改。参见:HDU1495非常可乐,也是一个倒水问题,只不过输入、输出以及限制条件不一样。

AC的C++语言程序如下:

/* UVA10603 Fill */

#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>

using namespace std;

const int MAXN = 200;

int a, b, c, d, maxd1, minamount;
bool notvist[MAXN+1][MAXN+1][MAXN+1];

struct node {
    int a, b, c, amount;
    bool operator < (const node& n) const {
        return amount > n.amount;
    }
};

int bfs()
{
    maxd1 = 0;
    minamount = 0;

    priority_queue<node> q;

    memset(notvist, true, sizeof(notvist));

    node f, v;
    f.c = c;
    f.a = 0;
    f.b = 0;
    f.amount=0;
    q.push(f);

    notvist[f.c][f.a][f.b] = false;

    while(!q.empty()) {
        f = q.top();
        q.pop();

        if(f.a == d || f.b == d || f.c == d)
            return f.amount;

        if(f.a < d && f.a > maxd1) {
            maxd1 = f.a;
            minamount = f.amount;
        }
        if(f.b < d && f.b > maxd1) {
            maxd1 = f.b;
            minamount = f.amount;
        }
        if(f.c < d && f.c > maxd1) {
            maxd1 = f.c;
            minamount = f.amount;
        }

        // c --> a
        if(f.c && a - f.a > 0) {
            if(f.c > a - f.a) {         // c > a的剩余容量
                v.c = f.c - (a - f.a);
                v.a = a;
                v.b = f.b;
                v.amount = f.amount + (a - f.a);
            } else {                    // c <= a的剩余容量
                v.c = 0;
                v.a = f.a + f.c;
                v.b = f.b;
                v.amount = f.amount + f.c;
            }
            if(notvist[v.c][v.a][v.b]) {
                notvist[v.c][v.a][v.b] = false;
                q.push(v);
            }
        }
        // c --> b
        if(f.c && b - f.b > 0) {
            if(f.c > b - f.b) {         // c > b的剩余容量
                v.c = f.c - (b - f.b);
                v.a = f.a;
                v.b = b;
                v.amount = f.amount + (b - f.b);
            } else {                    // c <= b的剩余容量
                v.c = 0;
                v.a = f.a;
                v.b = f.b + f.c;
                v.amount = f.amount + f.c;
            }
            if(notvist[v.c][v.a][v.b]) {
                notvist[v.c][v.a][v.b] = false;
                q.push(v);
            }
        }
        // a --> c
        if(f.a && c - f.c > 0) {
            if(f.a > c - f.c) {         // a > c的剩余容量
                v.c = c;
                v.a = f.a - (c - f.c);
                v.b = f.b;
                v.amount = f.amount + (c - f.c);
            } else {                    // a <= c的剩余容量
                v.c = f.c + f.a;
                v.a = 0;
                v.b = f.b;
                v.amount = f.amount + f.a;
            }
            if(notvist[v.c][v.a][v.b]) {
                notvist[v.c][v.a][v.b] = false;
                q.push(v);
            }
        }
        // a --> b
        if(f.a && b - f.b > 0) {
            if(f.a > b - f.b) {         // a > b的剩余容量
                v.c = f.c;
                v.a = f.a - (b - f.b);
                v.b = b;
                v.amount = f.amount + (b - f.b);
            } else {                    // a <= b的剩余容量
                v.c = f.c;
                v.a = 0;
                v.b = f.b + f.a;
                v.amount = f.amount + f.a;
            }
            if(notvist[v.c][v.a][v.b]) {
                notvist[v.c][v.a][v.b] = false;
                q.push(v);
            }
        }
        // b --> c
        if(f.b && c - f.c > 0) {
            if(f.b > c - f.c) {         // b > c的剩余容量
                v.c = c;
                v.a = f.a;
                v.b = f.b - (c - f.c);
                v.amount = f.amount + (c - f.c);
            } else {                    // b <= c的剩余容量
                v.c = f.c + f.b;
                v.a = f.a;
                v.b = 0;
                v.amount = f.amount + f.b;
            }
            if(notvist[v.c][v.a][v.b]) {
                notvist[v.c][v.a][v.b] = false;
                q.push(v);
            }
        }
        // b --> a
        if(f.b && a - f.a > 0) {
            if(f.b > a - f.a) {         // b > a的剩余容量
                v.c = f.c;
                v.a = a;
                v.b = f.b - (a - f.a);
                v.amount = f.amount + (a - f.a);
            } else {                    // b <= a的剩余容量
                v.c = f.c;
                v.a = f.a + f.b;
                v.b = 0;
                v.amount = f.amount + f.b;
            }
            if(notvist[v.c][v.a][v.b]) {
                notvist[v.c][v.a][v.b] = false;
                q.push(v);
            }
        }
    }

    return -1;
}

int main()
{
    int t;

    scanf("%d", &t);
    while(t--) {
        scanf("%d%d%d%d", &a, &b, &c, &d);

        int ans = bfs();

        if(ans < 0) {
            printf("%d %d\n", minamount, maxd1);
        } else
            printf("%d %d\n", ans, d);
    }

    return 0;
}


UVA10603 Fill

标签:

原文地址:http://blog.csdn.net/tigerisland45/article/details/52245254

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!