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;
}
posted @ 2020-06-10 22:07  RioTian  阅读(163)  评论(0编辑  收藏  举报