HDU1495 非常可乐

问题链接HDU1495 非常可乐

题意简述:平分液体问题。输入s、n和m三个数,分别代表可乐和2个杯子,三个容器可以互相倒,问能不能把s中的可乐平分,能的话输出最小倒杯子的次数,不能就输出NO。

问题分析:开始的时候,所有可乐在s中,2个杯子n和m都空着。过程中,可以将任何1个容器中的可乐倒到另外某个容器中,或将目标容器倒满,或将源容器倒空。因为容器没有刻度,只能这样。这个过程中,如果出现某个容器空,另外2个容器可乐相同则成功。如果开始的时候,可乐的容量是奇数,则不可能平分可乐。容器间可乐倒来倒去,每次有6种倒法,对这6种倒法进行试探即可。求的是最少倒的次数,所以可以用BFS实现。

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

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

/* HDU1495 非常可乐 */

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

using namespace std;

const int MAXN = 100;

int s, n, m, s2;
bool notvist[MAXN+1][MAXN+1][MAXN+1];

struct node {
    int s, n, m, level;
};

int bfs()
{
    if(s % 2 == 1)
        return -1;

    queue<node> q;

    s2 = s / 2;
    memset(notvist, true, sizeof(notvist));

    node f;
    f.s = s;
    f.n = 0;
    f.m = 0;
    f.level=0;
    q.push(f);

    notvist[f.s][f.n][f.m] = false;

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

        if((f.s == f.n && f.s == s2) || (f.s == f.m && f.s == s2) || (f.m == f.n && f.m == s2))
            return f.level;

        node v;

        // s --> n
        if(f.s && n - f.n > 0) {
            if(f.s > n - f.n) {         // s > n的剩余容量
                v.s = f.s - (n - f.n);
                v.n = n;
                v.m = f.m;
            } else {                    // s <= n的剩余容量
                v.s = 0;
                v.n = f.n + f.s;
                v.m = f.m;
            }
            if(notvist[v.s][v.n][v.m]) {
                notvist[v.s][v.n][v.m] = false;
                v.level = f.level + 1;
                q.push(v);
            }
        }
        // s --> m
        if(f.s && m - f.m > 0) {
            if(f.s > m - f.m) {         // s > m的剩余容量
                v.s = f.s - (m - f.m);
                v.n = f.n;
                v.m = m;
            } else {                    // s <= m的剩余容量
                v.s = 0;
                v.n = f.n;
                v.m = f.m + f.s;
            }
            if(notvist[v.s][v.n][v.m]) {
                notvist[v.s][v.n][v.m] = false;
                v.level = f.level + 1;
                q.push(v);
            }
        }
        // n --> s
        if(f.n && s - f.s > 0) {
            if(f.n > s - f.s) {         // n > s的剩余容量
                v.s = s;
                v.n = f.n - (s - f.s);
                v.m = f.m;
            } else {                    // n <= s的剩余容量
                v.s = f.s + f.n;
                v.n = 0;
                v.m = f.m;
            }
            if(notvist[v.s][v.n][v.m]) {
                notvist[v.s][v.n][v.m] = false;
                v.level = f.level + 1;
                q.push(v);
            }
        }
        // n --> m
        if(f.n && m - f.m > 0) {
            if(f.n > m - f.m) {         // n > m的剩余容量
                v.s = f.s;
                v.n = f.n - (m - f.m);
                v.m = m;
            } else {                    // n <= m的剩余容量
                v.s = f.s;
                v.n = 0;
                v.m = f.m + f.n;
            }
            if(notvist[v.s][v.n][v.m]) {
                notvist[v.s][v.n][v.m] = false;
                v.level = f.level + 1;
                q.push(v);
            }
        }
        // m --> s
        if(f.m && s - f.s > 0) {
            if(f.m > s - f.s) {         // m > s的剩余容量
                v.s = s;
                v.n = f.n;
                v.m = f.m - (s - f.s);
            } else {                    // m <= s的剩余容量
                v.s = f.s + f.m;
                v.n = f.n;
                v.m = 0;
            }
            if(notvist[v.s][v.n][v.m]) {
                notvist[v.s][v.n][v.m] = false;
                v.level = f.level + 1;
                q.push(v);
            }
        }
        // m --> n
        if(f.m && n - f.n > 0) {
            if(f.m > n - f.n) {         // m > n的剩余容量
                v.s = f.s;
                v.n = n;
                v.m = f.m - (n - f.n);
            } else {                    // m <= n的剩余容量
                v.s = f.s;
                v.n = f.n + f.m;
                v.m = 0;
            }
            if(notvist[v.s][v.n][v.m]) {
                notvist[v.s][v.n][v.m] = false;
                v.level = f.level + 1;
                q.push(v);
            }
        }
    }

    return -1;
}

int main()
{
    while(scanf("%d%d%d", &s, &n, &m) != EOF) {
        if(s == 0 && n == 0 && m == 0)
            break;

        int ans = bfs();

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

    return 0;
}

参考链接:非常可乐



posted on 2016-08-15 01:54  海岛Blog  阅读(184)  评论(0编辑  收藏  举报

导航