• 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
    ");
            else
                printf("%d
    ", ans);
        }
    
        return 0;
    }

    参考链接:非常可乐



  • 相关阅读:
    蓝桥杯_基础_杨辉三角
    蓝桥杯_基础_数组特征
    蓝桥杯_基础_美丽的图形
    脉象
    词根汇总
    蓝桥杯 入门训练 Fibonacci数列 解析
    制作tomcat重启.bat文件
    day23(023-递归练习)
    day27(027-反射&JDK新特性)
    day25(025-多线程(下)&GUI)
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564391.html
Copyright © 2020-2023  润新知