欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Pots POJ - 3414 (搜索+记录路径)

程序员文章站 2022-03-28 19:13:35
Pots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22688 Accepted: 9626 Special Judge Description You are given two pots, having the volu ......
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;
}