Pots POJ – 3414 (搜尋+記錄路徑)

千擺渡Qbd發表於2018-09-08
Pots
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 22688   Accepted: 9626   Special Judge

Description

You are given two pots, having the volume of A and B liters respectively. The following operations can be performed:

  1. FILL(i)        fill the pot i (1 ≤ ≤ 2) from the tap;
  2. DROP(i)      empty the pot i to the drain;
  3. 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.

Input

On the first and only line are the numbers AB, and C. These are all integers in the range from 1 to 100 and 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’.

Sample Input

3 5 4

Sample Output

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

Source

Northeastern Europe 2002, Western Subregion

 

題意:

有二個水壺,對水壺有三種操作:

1)FILL(i),將i水壺的水填滿;

2)DROP(i),將水壺i中的水全部倒掉;

3)POUR(i,j)將水壺i中的水倒到水壺j中,若水壺 j 滿了,則 i 剩下的就不倒了,問進行多少步操作,並且怎麼操作,輸出操作的步驟,兩個水壺中的水可以達到C這個水量。如果不可能則輸出impossible。初始時兩個水壺是空的,沒有水。

思路:

模擬一下,然後如果當前的狀態已經出現過了就說明不可以這樣子,必須要用其他操作,這個和poj3087的題目有點像,這裡還需要儲存一個路徑,這個和poj3984有點像,poj3984之前的部落格裡面用了遞迴的方式輸出路徑,這一回用了棧,兩種方法應該都可以做的,具體的看程式碼吧,註釋已經很清楚了

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
#define _e exp(1.0)
#define ll long long
const int maxn=110;
struct cup
{
    int x,y;            //a和b的當前水的狀態
    int step;
    int flag;           //標記操作,是操作幾
    cup *pre;           //記錄路徑的玩意兒
};
queue<cup>que;
stack<int>R;
int a,b,e;
int vis[maxn][maxn]={0};     //記錄當前的狀態是否到達過
int ans;

void bfs(int x,int y)
{
    cup c;
    cup t[317];           //目前瓶子裡剩餘的水量
    c.x=0;
    c.y=0;
    c.flag=0;
    c.pre=NULL;
    c.step=0;
    que.push(c);
    vis[x][y]=1;
    int count=-1;
    while(!que.empty())
    {
        count++;
        t[count]=que.front();
        que.pop();
        for(int i=1;i<=6;i++)
        {
            switch(i)
            {
                case 1:             //fill a
                    c.x=a;
                    c.y=t[count].y;
                    c.flag=1;
                    break;
                case 2:             //fill b
                    c.x=t[count].x;
                    c.y=b;
                    c.flag=2;
                    break;
                case 3:             //drop a
                    c.x=0;
                    c.y=t[count].y;
                    c.flag=3;
                    break;
                case 4:             //drop b
                    c.x=t[count].x;
                    c.y=0;
                    c.flag=4;
                    break;
                case 5:             //pour a to b
                    if(t[count].x>b-t[count].y)     //a可以裝滿b
                    {
                        c.x=t[count].x-(b-t[count].y);
                        c.y=b;
                    }
                    else                            //a不能裝滿b
                    {
                        c.x=0;
                        c.y=t[count].y+t[count].x;
                    }
                    c.flag=5;
                    break;
                case 6:           //pour b to a
                    if(t[count].y>a-t[count].x)     //b可以裝滿a
                    {
                        c.y=t[count].y-(a-t[count].x);
                        c.x=a;
                    }
                    else                            //b不可以裝滿a
                    {
                        c.x=t[count].x+t[count].y;
                        c.y=0;
                    }
                    c.flag=6;
                    break;
            }
            if(vis[c.x][c.y])
                continue;
            vis[c.x][c.y]=1;
            c.step=t[count].step+1;
            c.pre=&t[count];
            if(c.x==e || c.y==e)
            {
                ans=c.step;
                while(c.pre)
                {
                    R.push(c.flag);
                    c=*c.pre;
                }
                return;
            }
            que.push(c);
        }
    }
}
void print()
{
    while(!R.empty())
    {
        int i=R.top();
        R.pop();
        switch(i)
        {
            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;
        }
    }
}
int main()
{
    cin>>a>>b>>e;
    bfs(0,0);
    if(ans==0)
        cout<<"impossible"<<endl;
    else
    {
        cout<<ans<<endl;
        print();
    }
    return 0;
}

 

相關文章