[kuangbin] Topic 1 Simple Search for Pots POJ-3414 [BFS]

Keywords: iOS

[Title Description]
You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:
·FILL(i) fill the pot i (1 ≤ i ≤ 2) from the tap
·DROP(i) empty the pot i to the drain
·POUR(i,j) pour from pot i to pot j;after this operation either the pot j is full (and there may be some water left in the pot i),or the pot i is empty (and all its contents have been moved to the pot j)
Write a program to find the shortest possible sequence of these operations that will yield exactly C liters of water in one of the pots
Give you two containers, which can hold A and B liters respectively, and can perform the following operations:
1.FILL(i) fills the first container from the tap (1 < I < 2);
2.DROP(i) empties the water in the first container
3.POUR(i,j) pours the water in the first container into the jth container (after this operation, there are two results: first, the jth container is full and the ith container is still surplus; second, all the water in the ith container is poured into j, and the ith container is empty).
Now you're asked to write a program to find out if the water in any of these containers happens to have a C liter, to find out the minimum number of operands, and to give the operation process.

[Input]
On the first and only line are the numbers A, B, and C. These are all integers in the range from 1 to 100 and C ≤ max(A,B).
Only one line, containing three numbers A,B,C (1 <= A, B <= 100, C <= Max (A, B))

[Output]
The first line of the output must contain the length of the sequence of operations K.The following K lines must each describe one operation.If there are several sequences of minimal length,output any one of them.If the desired result can't be achieved,the first and only line of the file must contain the word 'impossible'.
The first line contains a number representing the minimum operand K
Subsequently, K lines give a specific operation once per line. If multiple answers match the minimum operand, output either of them. If you can't make either of the two containers satisfy exactly C-liter, output "impossible".

[Sample input]
3 5 4

[Sample output]
6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)

Topic link: https://cn.vjudge.net/problem/POJ-3414

Simulate six cases of bfs, record the whole process of BFS with t array, and restore path with * pre

The code is as follows (comparing garbage, combining six cases with arrays can reduce at least 100 lines):

#include <iostream>
#include <cstring>
#include <queue>
#include <utility>
#include <stack>
#include <algorithm>
using namespace std;
static const int MAXN=100;
int vis[MAXN+10][MAXN+10];
int a,b,c,ans;
struct Node{
    pair<int,int> c;
    int step;
    int flag;
    Node *pre;
};
queue<Node> Q;
stack<int> S;
void bfs(pair<int,int> n)
{
    Node t[1000];
    Q.push(Node{make_pair(0,0),0,0,NULL});
    vis[n.first][n.second]=1;
    int cnt=-1;
    while(!Q.empty())
    {
        cnt++;
        t[cnt]=Q.front();
        Q.pop();
        Node next;//fill 1
        next.c.first=a;
        next.c.second=t[cnt].c.second;
        next.flag=1;
        if(!vis[next.c.first][next.c.second])
        {
            vis[next.c.first][next.c.second]=1;
            next.pre=&t[cnt];
            next.step=t[cnt].step+1;
            if(next.c.first==c || next.c.second==c)
            {
                cout<<next.step<<endl;
                while(next.pre)
                {
                    S.push(next.flag);
                    next=*next.pre;
                }
                while(!S.empty())
                {
                    int op=S.top();
                    S.pop();
                    switch(op)
                    {
                        case 1:cout<<"FILL(1)"<<endl;break;
                        case 2:cout<<"FILL(2)"<<endl;break;
                        case 3:cout<<"DROP(1)"<<endl;break;
                        case 4:cout<<"DROP(2)"<<endl;break;
                        case 5:cout<<"POUR(1,2)"<<endl;break;
                        case 6:cout<<"POUR(2,1)"<<endl;break;
                    }
                }
                return;
            }
            Q.push(next);
        }
        next.c.first=t[cnt].c.first;//fill 2
        next.c.second=b;
        next.flag=2;
        if(!vis[next.c.first][next.c.second])
        {    
            vis[next.c.first][next.c.second]=1;
            next.pre=&t[cnt];
            next.step=t[cnt].step+1;
            if(next.c.first==c || next.c.second==c)
            {
                cout<<next.step<<endl;
                while(next.pre)
                {
                    S.push(next.flag);
                    next=*next.pre;
                }
                while(!S.empty())
                {
                    int op=S.top();
                    S.pop();
                    switch(op)
                    {
                        case 1:cout<<"FILL(1)"<<endl;break;
                        case 2:cout<<"FILL(2)"<<endl;break;
                        case 3:cout<<"DROP(1)"<<endl;break;
                        case 4:cout<<"DROP(2)"<<endl;break;
                        case 5:cout<<"POUR(1,2)"<<endl;break;
                        case 6:cout<<"POUR(2,1)"<<endl;break;
                    }
                }
                return;
            }
            Q.push(next);
        }
        next.c.first=0;//drop 1
        next.c.second=t[cnt].c.second;
        next.flag=3;
        if(!vis[next.c.first][next.c.second])
        {
            vis[next.c.first][next.c.second]=1;
            next.pre=&t[cnt];
            next.step=t[cnt].step+1;
            if(next.c.first==c || next.c.second==c)
            {
                cout<<next.step<<endl;
                while(next.pre)
                {
                    S.push(next.flag);
                    next=*next.pre;
                }
                while(!S.empty())
                {
                    int op=S.top();
                    S.pop();
                    switch(op)
                    {
                        case 1:cout<<"FILL(1)"<<endl;break;
                        case 2:cout<<"FILL(2)"<<endl;break;
                        case 3:cout<<"DROP(1)"<<endl;break;
                        case 4:cout<<"DROP(2)"<<endl;break;
                        case 5:cout<<"POUR(1,2)"<<endl;break;
                        case 6:cout<<"POUR(2,1)"<<endl;break;
                    }
                }
                return;
            }
            Q.push(next);
        }
        next.c.first=t[cnt].c.first;//drop 2
        next.c.second=0;
        next.flag=4;
        if(!vis[next.c.first][next.c.second])
        {
            vis[next.c.first][next.c.second]=1;
            next.pre=&t[cnt];
            next.step=t[cnt].step+1;
            if(next.c.first==c || next.c.second==c)
            {
                cout<<next.step<<endl;
                while(next.pre)
                {
                    S.push(next.flag);
                    next=*next.pre;
                }
                while(!S.empty())
                {
                    int op=S.top();
                    S.pop();
                    switch(op)
                    {
                        case 1:cout<<"FILL(1)"<<endl;break;
                        case 2:cout<<"FILL(2)"<<endl;break;
                        case 3:cout<<"DROP(1)"<<endl;break;
                        case 4:cout<<"DROP(2)"<<endl;break;
                        case 5:cout<<"POUR(1,2)"<<endl;break;
                        case 6:cout<<"POUR(2,1)"<<endl;break;
                    }
                }
                return;
            }
            Q.push(next);
        }
        next.c.first=t[cnt].c.first-min(t[cnt].c.first,b-t[cnt].c.second);//pour 1 2
        next.c.second=t[cnt].c.second+min(t[cnt].c.first,b-t[cnt].c.second);
        next.flag=5;
        if(!vis[next.c.first][next.c.second])
        {
            vis[next.c.first][next.c.second]=1;
            next.pre=&t[cnt];
            next.step=t[cnt].step+1;
            if(next.c.first==c || next.c.second==c)
            {
                cout<<next.step<<endl;
                while(next.pre)
                {
                    S.push(next.flag);
                    next=*next.pre;
                }
                while(!S.empty())
                {
                    int op=S.top();
                    S.pop();
                    switch(op)
                    {
                        case 1:cout<<"FILL(1)"<<endl;break;
                        case 2:cout<<"FILL(2)"<<endl;break;
                        case 3:cout<<"DROP(1)"<<endl;break;
                        case 4:cout<<"DROP(2)"<<endl;break;
                        case 5:cout<<"POUR(1,2)"<<endl;break;
                        case 6:cout<<"POUR(2,1)"<<endl;break;
                    }
                }
                return;
            }
            Q.push(next);
        }
        next.c.first=t[cnt].c.first+min(t[cnt].c.second,a-t[cnt].c.first);//pour 2 1
        next.c.second=t[cnt].c.second-min(t[cnt].c.second,a-t[cnt].c.first);
        next.flag=6;
        if(!vis[next.c.first][next.c.second])
        {
            vis[next.c.first][next.c.second]=1;
            next.pre=&t[cnt];
            next.step=t[cnt].step+1;
            if(next.c.first==c || next.c.second==c)
            {
                cout<<next.step<<endl;
                while(next.pre)
                {
                    S.push(next.flag);
                    next=*next.pre;
                }
                while(!S.empty())
                {
                    int op=S.top();
                    S.pop();
                    switch(op)
                    {
                        case 1:cout<<"FILL(1)"<<endl;break;
                        case 2:cout<<"FILL(2)"<<endl;break;
                        case 3:cout<<"DROP(1)"<<endl;break;
                        case 4:cout<<"DROP(2)"<<endl;break;
                        case 5:cout<<"POUR(1,2)"<<endl;break;
                        case 6:cout<<"POUR(2,1)"<<endl;break;
                    }
                }
                return;
            }
            Q.push(next);
        }
    }
    cout<<"impossible"<<endl;
    return;
}
int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0),cout.tie(0);
    cin>>a>>b>>c;
    bfs(make_pair(0,0));
    return 0;
}

Posted by fizzystutter on Sun, 04 Aug 2019 00:49:43 -0700