POJ 3414 Pots(深搜并打印路径)

POJ 3414 Pots(深搜并打印路径)

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.

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).

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)

解题思路:

1.两遍dfs,第一遍找到最小的倒水次数,第二遍打印路径
2.倒水问题:模拟倒水的6种情况

#include<iostream>//代码稍微有点长,但是思路很简单
#include<cstdlib>
#include<cstring>
#include<stack>
#define INF 0x7fffffff
using namespace std;
typedef struct node{
    int x;//操作x==1代表操作FILL,x==2代表操作DROP
    int y;//代表操作的参数如x==1,y==2则代表FILL(2)
    int z;
}Node;
Node temp;
stack<Node>s;//利用栈记录路径
int book[110][110];//标记数组
int flag=0;
int mins=INF;
int a,b,tol;
void dfs(int x,int y,int sum,int f,int fx,int fy) {
    //参数x,y记录第1个和第2个水杯的水量,sum代表操作次数,
    //f代表当前操作,fx,fy是操作的两个参数
    if(x==tol||y==tol) {//当符合情况时更新最小值
        if(sum<mins){
            mins=sum;
        }
        return;
    }
    int xx,yy,ff,ffx,ffy;
    if(x!=0) {//第一种情况,当第一个水杯有水时全部倒出DROP(1)
        xx=0;
        yy=y;
        ff=2;//记录是第几个操作
        ffx=1;//记录操作的第一个参数
        ffy=0;//记录操作的第二个参数(只有在POUR操作下才有)
        if(book[xx][yy]==0){//没出现过此种状态
            book[xx][yy]=1;
            dfs(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
        }
    }
    if(y!=0) {//第2种情况,当第2个水杯有水时全部倒出DROP(2)
        xx=x;
        yy=0;
        ff=2;
        ffx=2;
        ffy=0;
        if(book[xx][yy]==0){
            book[xx][yy]=1;
            dfs(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
        }
    }
    if(x!=a) {第3种情况,当第1个水杯没有装满时倒满水FILL(1)
        xx=a;
        yy=y;
        ff=1;
        ffx=1;
        ffy=0;
       if(book[xx][yy]==0){
            book[xx][yy]=1;
            dfs(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
        }
    }
    if(y!=b) {//第4种情况,当第2个水杯没有装满时倒满水FILL(2)
        xx=x;
        yy=b;
        ff=1;
        ffx=2;
        ffy=0;
        if(book[xx][yy]==0){
            book[xx][yy]=1;
            dfs(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
        }
    }
    if(x!=a&&y!=0) {//第5种情况,当第1个水杯不满,第2个水杯有水时,
    //将第二个水杯的水倒入第一个水杯POUR(2,1)
        xx=min(x+y,a);
        yy=y-(xx-x);
        ff=3;
        ffx=2;
        ffy=1;
        if(book[xx][yy]==0){
            book[xx][yy]=1;
            dfs(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
        }
    }
    if(x!=0&&y!=b) {
    第6种情况,当第2个水杯不满,第1个水杯有水时,
    //将第1个水杯的水倒入第2个水杯POUR(1,2)
        yy=min(x+y,b);
        xx=x-(yy-y);
        ff=3;
        ffx=1;
        ffy=2;
        if(book[xx][yy]==0){
            book[xx][yy]=1;
            dfs(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
        }
    }
    return;
}
void prints(int f,int fx,int fy){//打印一步的操作
    if(f==1){
        cout<<"FILL("<<fx<<")"<<endl;
    }
    else if(f==2){
        cout<<"DROP("<<fx<<")"<<endl;
    }
    else if(f==3){
        cout<<"POUR("<<fx<<","<<fy<<")"<<endl;
    }
}
void print(int x,int y,int sum,int f,int fx,int fy) {//寻找路径并记录路径
    if(x==tol||y==tol) {
        if(sum==mins){//当达到最小值时记录此路径
            flag=1;
        }
        return;
    }
    int xx,yy,ff,ffx,ffy;
    if(x!=0) {//和上边的dfs思路一样,只不过多了一个判断
        xx=0;
        yy=y;
        ff=2;
        ffx=1;
        ffy=0;
        if(book[xx][yy]==0){
            book[xx][yy]=1;
            print(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
            if(flag==1){//多个这个判断
                temp.x=ff;
                temp.y=ffx;
                temp.z=ffy;
                s.push(temp);
                return;
            }
        }
    }
    if(y!=0) {
        xx=x;
        yy=0;
        ff=2;
        ffx=2;
        ffy=0;
        if(book[xx][yy]==0){
            book[xx][yy]=1;
            print(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
            if(flag==1){
                temp.x=ff;
                temp.y=ffx;
                temp.z=ffy;
                s.push(temp);
                return;
            }
        }
    }
    if(x!=a) {
        xx=a;
        yy=y;
        ff=1;
        ffx=1;
        ffy=0;
       if(book[xx][yy]==0){
            book[xx][yy]=1;
            print(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
            if(flag==1){
                temp.x=ff;
                temp.y=ffx;
                temp.z=ffy;
                s.push(temp);
                return;
            }
        }
    }
    if(y!=b) {
        xx=x;
        yy=b;
        ff=1;
        ffx=2;
        ffy=0;
        if(book[xx][yy]==0){
            book[xx][yy]=1;
            print(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
            if(flag==1){
                temp.x=ff;
                temp.y=ffx;
                temp.z=ffy;
                s.push(temp);
                return;
            }
        }
    }
    if(x!=a&&y!=0) {
        xx=min(x+y,a);
        yy=y-(xx-x);
        ff=3;
        ffx=2;
        ffy=1;
        if(book[xx][yy]==0){
            book[xx][yy]=1;
            print(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
            if(flag==1){
                temp.x=ff;
                temp.y=ffx;
                temp.z=ffy;
                s.push(temp);
                return;
            }
        }
    }
    if(x!=0&&y!=b) {
        yy=min(x+y,b);
        xx=x-(yy-y);
        ff=3;
        ffx=1;
        ffy=2;
        if(book[xx][yy]==0){
            book[xx][yy]=1;
            print(xx,yy,sum+1,ff,ffx,ffy);
            book[xx][yy]=0;
            if(flag==1){
                temp.x=ff;
                temp.y=ffx;
                temp.z=ffy;
                s.push(temp);
                return;
            }
        }
    }
    return;
}
int main() {
    cin>>a>>b>>tol;
    memset(book,0,sizeof(book));
    book[0][0]=1;
    dfs(0,0,0,0,0,0);//寻找最少倒换几次
    if(mins!=INF){
        cout<<mins<<endl;
        memset(book,0,sizeof(book));
        book[0][0]=1;
        print(0,0,0,0,0,0);//寻找路径
        while(!s.empty()){//输出路径
            temp=s.top();
            s.pop();
            prints(temp.x,temp.y,temp.z);
        }
    }
    else{
        cout<<"impossible"<<endl;
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值