zoukankan      html  css  js  c++  java
  • POJ3414 Pots( BFS搜索)

    题目:

    给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作

    FILL(i) 将第i个容器从水龙头里装满(1 ≤ i ≤ 2);

    DROP(i) 将第i个容器抽干

    POUR(i,j) 将第i个容器里的水倒入第j个容器(这次操作结束后产生两种结果,一是第j个容器倒满并且第i个容器依旧有剩余,二是第i个容器里的水全部倒入j中,第i个容器为空)

    现在要求你写一个程序,来找出能使其中任何一个容器里的水恰好有C升,找出最少操作数并给出操作过程

    输入:

    有且只有一行,包含3个数A,B,C(1<=A,B<=100,C<=max(A,B))

    输出:

    第一行包含一个数表示最小操作数K

    随后K行每行给出一次具体操作,如果有多种答案符合最小操作数,输出他们中的任意一种操作过程,如果你不能使两个容器中的任意一个满足恰好C升的话,输出“impossible”

    分析:

    简单的BFS,难点在于回溯,给每个状态用数组记录路径

    代码

    #include<iostream>
    #include<queue>
    #include<string>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    int a, b, c;
    int used[105][105];
    struct node
    {
        int x, y;
        int flag;
        int path[1005];//数组中0-5分别表示6种不同操作
    }st;
    string print[6] = { "FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)" };
    void bfs()
    {
        queue<node> q;
        for (int i = 0; i <= a; ++i)
        {
            for (int j = 0; j <= b; ++j)
                used[i][j] = INF;
        }
        memset(used, 0, sizeof(used));
        st.x = 0, st.y = 0;
        st.flag = 0;
        memset(st.path, -1, sizeof(st.path));
        q.push(st);
        used[st.x][st.y] = 1;
        while (q.size())
        {
            node temp = q.front();
            q.pop();
            if (temp.x == c || temp.y == c)
            {
                cout << temp.flag << endl;
                for (int i = 0; i < temp.flag; ++i)
                    cout << print[temp.path[i]] << endl;
                return;
            }
            for (int i = 0; i < 6; ++i)
            {
                node now = temp;
                now.flag++;
                if (i == 0 && now.x != a)
                {
                    now.x = a;
                    if (!used[now.x][now.y])
                    {
                        used[now.x][now.y] = 1;
                        now.path[temp.flag] = 0;
                        q.push(now);
                    }
                }
                else if (i == 1 && now.y != b)
                {
                    now.y = b;
                    if (!used[now.x][now.y])
                    {
                        used[now.x][now.y] = 1;
                        now.path[temp.flag] = 1;
                        q.push(now);
                    }
                }
                else if (i == 2 && now.x != 0)
                {
                    now.x = 0;
                    if (!used[now.x][now.y])
                    {
                        used[now.x][now.y] = 1;
                        now.path[temp.flag] = 2;
                        q.push(now);
                    }
                }
                else if (i == 3 && now.y != 0)
                {
                    now.y = 0;
                    if (!used[now.x][now.y])
                    {
                        used[now.x][now.y] = 1;
                        now.path[temp.flag] = 3;
                        q.push(now);
                    }
                }
                else if (i == 4)
                {
                    if (now.x + now.y > b)
                    {
                        now.x -= b - now.y;
                        now.y = b;
                    }
                    else
                    {
                        now.y += now.x;
                        now.x = 0;
                    }
                    if (!used[now.x][now.y])
                    {
                        used[now.x][now.y] = 1;
                        now.path[temp.flag] = 4;
                        q.push(now);
                    }
                }
                else if (i == 5)
                {
                    if (now.x + now.y > a)
                    {
                        now.y -= a - now.x;
                        now.x = a;
                    }
                    else
                    {
                        now.x += now.y;
                        now.y = 0;
                    }
                    if (!used[now.x][now.y])
                    {
                        used[now.x][now.y] = 1;
                        now.path[temp.flag] = 5;
                        q.push(now);
                    }
                }
            }
        }
        cout << "impossible" << endl;
    }
    int main()
    {
        cin >> a >> b >> c;
        bfs();
        return 0;
    }
    
  • 相关阅读:
    给最小化托盘增加右键菜单
    (转)c#实现开机自启动
    Socket代码
    (转)C# Socket简单例子(服务器与客户端通信)
    (转)C# Socket异步通信
    (转)winform pictureBox后台显示图片
    验证DataGridView单元格的值
    批处理判断是否有.net环境
    Winform判断是否已启动
    linux 下 apache启动、停止、重启命令
  • 原文地址:https://www.cnblogs.com/RioTian/p/13089521.html
Copyright © 2011-2022 走看看