【解题报告】POJ 3414 Pots(bfs/保存操作)

原题链接

参考博客:
POJ - 3414 Pots (倒水问题 BFS + 打印路径)---- stormjing7
感谢dalao的点拨

题意

有两个杯子,容量分别为a,b,可以对这两个杯子进行以下的操作:

  • FILL(i) 装满第i个杯子
  • DROP(i) 把第i个杯子倒空
  • POUR(i, j) 把第i个杯子中的水倒入第j个杯子中,直到第i个杯子倒完或第j个杯子倒满
    问是否有有限个操作使得两个杯子中有杯子所装的水恰好为c,如果有,需要输出最小步数的操作和每一步具体的操作。如果没有,输出"impossible"

思路

因为题目要求求最少的步数,因此很容易想到bfs, 但是让我感到困难的地方在于如何把路径(每一步操作)存下来。起初我想的是把每一步操作存入一个结构体中,并且把遍历过的节点保存下结构体的下标,后来发现并行不通。遂翻看dalao的题解,恍然大悟。其实所有的操作也就只有6个,我们可以用一个常数字符串数组存下每一种操作,然后把每一次的操作存在一个数组里即可,保存路径新方法get!

#include <iostream>
#include <queue>
#include <string>
int a, b, c;
using namespace std;
string str[] = {"", "FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};
struct status
{
    int x, y;
    string s;
    int steps;
    status(int x, int y, string s, int steps):x(x), y(y), s(s), steps(steps){};
};
bool vis[110][110];
void bfs()
{
    queue<status> qst;
    qst.push(status(0, 0, "", 0));
    while(!qst.empty())
    {
        status temp = qst.front();
        qst.pop();
        if(temp.x == c || temp.y == c)
        {
            cout<<temp.steps<<endl;
            for(int i=0; i<temp.s.size(); i++)
            {
                cout<<str[temp.s[i] - '0']<<endl;
            }
            return;
        }
        vis[temp.x][temp.y] = true;
        if(temp.x < a)
        {
            if(!vis[a][temp.y])
            {
                qst.push(status(a, temp.y, temp.s+"1", temp.steps+1));
            }
        }
        if(temp.y < b)
        {
            if(!vis[temp.x][b])
            {
                qst.push(status(temp.x, b, temp.s+"2", temp.steps+1));
            }
        }
        if(temp.x > 0)
        {
            if(!vis[0][temp.y])
            {
                qst.push(status(0, temp.y, temp.s+"3", temp.steps+1));
            }
        }
        if(temp.y > 0)
        {
            if(!vis[temp.x][0])
            {
                qst.push(status(temp.x, 0, temp.s+"4", temp.steps+1));
            }

        }
        if(temp.x > 0 && temp.y < b)
        {
            int tempx = temp.x-min(temp.x, b-temp.y);
            int tempy = temp.y+min(temp.x, b-temp.y);
            if(!vis[tempx][tempy])
            {
                qst.push(status(tempx, tempy, temp.s+"5", temp.steps+1));
            }
        }
        if(temp.x < a && temp.y > 0)
        {
            int tempx = temp.x + min(temp.y, a-temp.x);
            int tempy = temp.y - min(temp.y, a-temp.x);
            if(!vis[tempx][tempy])
            {
                qst.push(status(tempx, tempy, temp.s+"6", temp.steps+1));
            }
        }
    }
    cout<<"impossible"<<endl;
}
int main()
{
    cin>>a>>b>>c;
    bfs();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42772300/article/details/88671916