POJ - 3414 Pots BFS + 记录并输出路径

POJ - 3414 Pots

题意:

给你两个杯子的容量 和 最后杯子中剩余水的容量。有三种操作方式

  1. FILL(i)        将第 i 个杯子装满水
  2. DROP(i)      将第 i 个杯子的水倒空
  3.  POUR(i,j)     将第 i 个杯子中的水倒入第 j 个杯子中     可能有两种情况:(1) i 杯子中的水还没全倒入 j 杯子中 j 杯子就满了,此时 i 杯子中还有剩余,(2)i 杯子中的水全倒入 j 杯子中,j 杯子没有溢出。

思路:

一共有6种不同的操作,直接 bfs 就行。难的是如何将路径记录下来并输出。

参考了大佬的博客:https://blog.csdn.net/u012860063/article/details/37768979

方法是在结构体中用一个指针记录他的上一个状态,在找到结果时通过指针将他的每一步操作存到栈中。

此题与POJ - 1606 Jugs 相同

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
int vis[110][110];  //记录当前状态是否已经到达过
int a,b,c,ans;
struct node
{
    int x,y;  //两个杯子分别有多少水
    int step;  
    int flag;  //操作
    node *pre;  //上一步操作的结构体
};
queue<node> q;
stack<int> s;
void bfs(int x,int y)
{
    node h;
    node w[1000]; //数组的地址不相同,所以不能用单个结构体变量(否则取地址时地址会相同)
    h.x = x;
    h.y = y;
    h.step = 0;
    h.flag = 0;
    h.pre = NULL;
    vis[h.x][h.y] = 1;
    q.push(h);
    int cnt = -1;
    while(!q.empty())
    {
        w[++cnt] = q.front();
        q.pop();
        for(int i=1;i<=6;i++)
        {
            switch(i)
            {
                case 1:         //FILL(1)
                    h.x = a;
                    h.y = w[cnt].y;
                    h.flag = 1;
                    break;
                case 2:        //FILL(2) 
                    h.x = w[cnt].x;
                    h.y = b;
                    h.flag = 2;
                    break;
                case 3:        //DROP(1)
                    h.x = 0;
                    h.y = w[cnt].y;
                    h.flag = 3;
                    break;
                case 4:         //DROP(2)
                    h.x = w[cnt].x;
                    h.y = 0;
                    h.flag = 4;
                    break;
                case 5:         //POUR(1,2)
                    if(w[cnt].x > b-w[cnt].y)
                    {
                        h.x = w[cnt].x-(b-w[cnt].y);
                        h.y = b;
                    }
                    else
                    {
                        h.x = 0;
                        h.y = w[cnt].y+w[cnt].x;
                    }
                    h.flag = 5;
                    break;
                case 6:        //POUR(2,1)
                    if(w[cnt].y > a-w[cnt].x)
                    {
                        h.x = a;
                        h.y = w[cnt].y-(a-w[cnt].x);
                    }
                    else
                    {
                        h.x = w[cnt].x+w[cnt].y;
                        h.y = 0;
                    }
                    h.flag = 6;
                    break;
            }
            if(vis[h.x][h.y])
                continue;
            vis[h.x][h.y] = 1;
            h.step = w[cnt].step+1;
            h.pre = &w[cnt];

            if(h.x==c || h.y==c)
            {
                ans = h.step;
                while(h.pre)
                {
                    s.push(h.flag);
                    h = *h.pre;
                }
                return ;
            }
            q.push(h);
        }
    }
}
void print()
{
    while(!s.empty())
    {
        switch(s.top())
        {
            case 1:
                printf("FILL(1)\n");
                break;
            case 2:
                printf("FILL(2)\n");
                break;
            case 3:
                printf("DROP(1)\n");
                break;
            case 4:
                printf("DROP(2)\n");
                break;
            case 5:
                printf("POUR(1,2)\n");
                break;
            case 6:
                printf("POUR(2,1)\n");
                break;
        }
        s.pop();
    }
}
int main()
{
    scanf("%d%d%d",&a,&b,&c);
    ans = 0;
    memset(vis,0,sizeof(vis));
    bfs(0,0);
    if(ans)
    {
        printf("%d\n",ans);
        print();
    }
    else
        printf("impossible\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41837216/article/details/87897805