Pots POJ - 3414

Pots POJ - 3414

题目地址:
传送门(vj)

小明给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作
FILL(i)        将第i个容器从水龙头里装满(1 ≤ i ≤ 2);

DROP(i)        将第i个容器抽干

POUR(i,j)      将第i个容器里的水倒入第j个容器(这次操作结束后产生两种结果,一是第j个容器倒满并且第i个容器依旧有剩余,
               二是第i个容器里的水全部倒入j中,第i个容器为空)

现在要求你写一个程序,来找出能使其中任何一个容器里的水恰好有C升,找出最少操作数并给出操作过程
#include<cmath>
#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=9999+10;
struct cup
{
public:
    int a,b;
    vector<char> st;
    cup(int a=0,int b=0):a(a),b(b) {}
    cup(const cup &t){
        a=t.a;b=t.b;st=t.st;
    }
    bool operator == (const cup & t)const
    {
        if(a!=t.a&&b!=t.b)
            return false;
        return true;
    }
    bool operator != (const cup & t)const
    {
        if(a!=t.a&&b!=t.b)
            return true;
        return false;
    }
};
int main()
{
//    freopen("1.txt","r",stdin);
    int a,b,c;
    cin>>a>>b>>c;
    int flag[150][150]= {0};
    memset(flag,0,sizeof(flag));//不知道为啥,不加这一句就没有初始化成功,在这里卡了有一会,如果有知道的可以评论区滴滴一下,
    cup be(0,0);
    cup p=be,en(c,c);
    queue<cup>qu;
    qu.push(be);
    flag[0][0]=1;
    //
    //  1 表示装满a
    //  2 表示装满b
    //  3 表示将a倒掉
    //  4 表示将b倒掉
    //  5 表示将a->b
    //  6 表示将b->a
    //
    while(p.a!=c&&p.b!=c){
        if(p.a<a) {//把a倒满
            cup pp(p);
            pp.a=a;
            if(flag[a][pp.b]==0){
                flag[a][pp.b]=1;
                pp.st.push_back('1');
                qu.push(pp);
            }

        }
        if(p.b<b) {//把b倒满
            cup pp(p);
            pp.b=b;
            if(flag[pp.a][b]==0){
                flag[pp.a][b]=1;
                pp.st.push_back('2');
                qu.push(pp);
            }
        }
        if(p.b>0) {//把b倒掉
            cup pp(p);
            pp.b=0;
            if(flag[pp.a][0]==0)
            {
                flag[pp.a][0]=1;
                pp.st.push_back('4');
                qu.push(pp);

            }
        }
        if(p.a>0) {//把a倒掉
            cup pp(p);
            pp.a=0;
            if(flag[0][pp.b]==0)
            {
                flag[0][pp.b]=1;
                pp.st.push_back('3');
                qu.push(pp);
            }
        }
        if(p.a>0&&p.b<b){ //a往b里倒
            cup pp(p);
            int l=b-pp.b;//  b里面差的
            if(pp.a<l){
                pp.b+=pp.a;pp.a=0;
            }
            else{
                pp.a-=(b-pp.b);pp.b=b;
            }
            if(flag[pp.a][pp.b]==0){
                flag[pp.a][pp.b]=1;
                pp.st.push_back('5');
                qu.push(pp);
            }
        }
        if(p.b>0&&p.a<a){//b往a里面倒
            cup pp(p);
            int l=a-pp.a;//  a里面差的
            if(pp.b<l){
                pp.a+=pp.b;pp.b=0;
            }
            else{
                pp.b-=(a-pp.a);pp.a=a;
            }
            if(flag[pp.a][pp.b]==0){
                flag[pp.a][pp.b]=1;
                pp.st.push_back('6');
                qu.push(pp);
            }
        }
        qu.pop();
        if(qu.empty())break;
        p=qu.front();
    }
    if(p==en){
        int l=p.st.size();
        cout<<l<<endl;
        for(int i=0; i<l; i++){
            switch(p.st[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;
            }
        }
    }
    else
        cout<<"impossible"<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值