POJ3414-POTS

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

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

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

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

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

Input

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

Output

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

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

Sample Input

3 5 4

Sample Output

6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)

思路:很明显要用BFS来做,题不难,主要是需要比较麻烦,需要不断将满足条件的压入队列,然后再不断取出来判断,另外需要用数组标记,用一个结构体数组来存放父节点,方便最后输出。

#include<set>
#include<map>
#include<stack>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e2 + 10;
int A, B, C;
struct node
{
    int x, y;
    int step;
    int f;
};
node fa[maxn * 3][maxn * 3][maxn * 3];
bool vis[maxn * 10][maxn * 10];
bool flag = false;
void bfs()
{
    queue<node> q;
    q.push(node{0, 0, 0});
    int cnt = 0;
    while(!q.empty())
    {
        node tmp = q.front();
        q.pop();
        if(tmp.x == C || tmp.y == C)
        {
            flag = true;
            stack<int> que;
            cout << tmp.step << endl;
            node pre = tmp;
            while(1)
            {
                if(pre.x == 0 && pre.y == 0 || pre.step == 0)
                    break;
                que.push(pre.f);
                pre = fa[pre.x][pre.y][pre.step];
            }
            while(!que.empty())
            {
                int tt = que.top();
                que.pop();
                if(tt == 1)
                    cout << "FILL(1)" << endl;
                else if(tt == 2)
                    cout << "FILL(2)" << endl;
                else if(tt == 3)
                    cout << "DROP(1)" << endl;
                else if(tt == 4)
                    cout << "DROP(2)" << endl;
                else if(tt == 5 || tt == 6)
                    cout << "POUR(1,2)" << endl;
                else if(tt == 7 || tt == 8)
                    cout << "POUR(2,1)" << endl;
            }
            return;
        }
        if(tmp.x < A && !vis[A][tmp.y])
        {
            vis[A][tmp.y] = true;
            q.push(node{A, tmp.y, tmp.step + 1, 1});
            fa[A][tmp.y][tmp.step + 1] = tmp;
        }
        if(tmp.y < B && !vis[tmp.x][B])
        {
            vis[tmp.x][B] = true;
            q.push(node{tmp.x, B, tmp.step + 1, 2});
            fa[tmp.x][B][tmp.step + 1] = tmp;
        }
        if(tmp.x > 0 && !vis[0][tmp.y])
        {
            vis[0][tmp.y] = true;
            q.push(node{0, tmp.y, tmp.step + 1, 3});
            fa[0][tmp.y][tmp.step + 1] = tmp;
        }
        if(tmp.y > 0 && !vis[tmp.x][0])
        {
            vis[tmp.x][0] = true;
            q.push(node{tmp.x, 0, tmp.step + 1, 4});
            fa[tmp.x][0][tmp.step + 1] = tmp;
        }
        if(tmp.x > 0 && tmp.y < B)
        {
            int num = tmp.y + tmp.x;
            if(num > B && !vis[num - B][B])
            {
                vis[num - B][B] = true;
                q.push(node{num - B, B, tmp.step + 1, 5});
                fa[num - B][B][tmp.step + 1] = tmp;
            }
            else if(!vis[0][num])
            {
                vis[0][num] = true;
                q.push(node{0, num, tmp.step + 1, 6});
                fa[0][num][tmp.step + 1] = tmp;
            }
        }
        if(tmp.x < A && tmp.y > 0)
        {
            int num = tmp.y + tmp.x;
            if(num > A && !vis[A][num - A])
            {
                vis[A][num - A] = true;
                q.push(node{A, num - A, tmp.step + 1, 7});
                fa[A][num - A][tmp.step + 1] = tmp;
            }
            else if(!vis[num][0])
            {
                vis[num][0] = true;
                q.push(node{num, 0, tmp.step + 1, 8});
                fa[num][0][tmp.step + 1] = tmp;
            }
        }
    }
}
int main()
{
    cin >> A >> B >> C;
    bfs();
    if(!flag)
        cout << "impossible" << endl;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值