poj3414 Pots

题目:http://poj.org/problem?id=3414

题意:给你a,b,c三个容积的杯子,问通过a,b(不使用c)什么操作能够得到c升的水。包括6中操作。

想法:bfs,六个状态。关键是要回溯步骤,用栈来保存,正好倒序输出。


代码

#include<iostream>
#include<queue>
#include<stack>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
struct Node{

    int x,y;
    int meth;
    int step;
};
Node node[105][105];
queue<int>t,s;
stack <int> pre;
bool vis[105][105];
int a,b,c;

int main(){
    while(~scanf("%d%d%d",&a,&b,&c)){
        memset(node,-1,sizeof(node));
        while(!t.empty())  t.pop();
        while(!s.empty())  s.pop();
        t.push(0),s.push(0);
        node[0][0].step=0;
        while(!t.empty()){
            int ex=s.front();
            int ey=t.front();
            if(ex==c||ey==c)  break;
            s.pop(),t.pop();
            int num=node[ex][ey].step;
            if(node[a][ey].step==-1){
                node[a][ey].meth=1;
                node[a][ey].x=ex;
                node[a][ey].y=ey;
                node[a][ey].step=num+1;
                s.push(a),t.push(ey);
            }
            if(node[ex][b].step==-1){
                node[ex][b].meth=2;
                node[ex][b].x=ex;
                node[ex][b].y=ey;
                node[ex][b].step=num+1;
                s.push(ex),t.push(b);
            }
            if(node[0][ey].step==-1){
                node[0][ey].meth=3;
                node[0][ey].x=ex;
                node[0][ey].y=ey;
                node[0][ey].step=num+1;
                s.push(0),t.push(ey);
            }
            if(node[ex][0].step==-1){
                node[ex][0].meth=4;
                node[ex][0].x=ex;
                node[ex][0].y=ey;
                node[ex][0].step=num+1;
                s.push(ex),t.push(0);
            }
            int tx=max(ex+ey-b,0);
            int ty=min(b,ex+ey);
            if(node[tx][ty].step==-1){
                node[tx][ty].meth=5;
                node[tx][ty].x=ex;
                node[tx][ty].y=ey;
                node[tx][ty].step=num+1;
                s.push(tx),t.push(ty);
            }
            tx=min(a,ex+ey);
            ty=max(0,ex+ey-a);
            if(node[tx][ty].step==-1){
                node[tx][ty].meth=6;
                node[tx][ty].x=ex;
                node[tx][ty].y=ey;
                node[tx][ty].step=num+1;
                s.push(tx),t.push(ty);
            }
        }

        if(s.empty())
            cout<<"impossible"<<endl;
        else{
            while(!pre.empty())  pre.pop();
            int px=s.front();
            int py=t.front();
            cout<<node[px][py].step<<endl;
            while(node[px][py].meth!=-1){
                pre.push(node[px][py].meth);
                int bx=node[px][py].x;
                int by=node[px][py].y;
                px=bx,py=by;
            }

            while(!pre.empty()){
                int m=pre.top();
                pre.pop();
                switch(m){
                    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 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值