poj 3414 Pots(bfs)

题目大意:

        你有两个瓶子,容量分别为A,B,有以下三种操作:

        1.FILL(i)          将i灌满。

        2.DROP(i)      将i倒空。

        3.POUR(i,j)    将i中的水倒入j中。可能j已满,i没倒空或j未满,i已空。

        问最少操作几次可以使其中一个杯子容量为C,若无法成立,则输出"impossible"。

解题思路:

        从A为空,B为空为起始状态开始宽搜,一共有6个方向。

代码:

#include <iostream>
#include <cstring>
#include <string>

using namespace std;

struct element{
    int a,b,step,before,
        operation;//0代表fill(a),1代表fill(b),2代表drop(a),3代表drop(b),4代表pour(a,b),5代表pour(b,a);
    element(){};
    element(int _a,int _b,int _step,int _before,int _operation){
        a = _a;
        b = _b;
        step = _step;
        before = _before;
        operation = _operation;
    }
};

element q[10005];
int head,root;
bool f[105][105];
int a,b,c;
int ans[10005];
string s[6];

int main()
{
    cin >> a >> b >> c;
    s[0] = "FILL(1)";
    s[1] = "FILL(2)";
    s[2] = "DROP(1)";
    s[3] = "DROP(2)";
    s[4] = "POUR(1,2)";
    s[5] = "POUR(2,1)";
    memset(f,true,sizeof(f));
    //初始化队列
    q[0].a = 0;
    q[0].b = 0;
    q[0].step = 0;
    q[0].before = -1;
    q[0].operation = -1;
    head = 0;
    root = 1;
    f[0][0] = false;
    //bfs
    while(head < root){
       element temp;
       temp = q[head];
       if(temp.a == c || temp.b == c) break;
       //fill(1)
       if(f[a][temp.b]){f[a][temp.b] = false; q[root] = element(a,temp.b,temp.step+1,head,0); root ++;}
       //fill(2)
       if(f[temp.a][b]){f[temp.a][b] = false; q[root] = element(temp.a,b,temp.step+1,head,1); root ++;}
       //drop(1)
       if(f[0][temp.b]){f[0][temp.b] = false; q[root] = element(0,temp.b,temp.step+1,head,2); root ++;}
       //drop(2)
       if(f[temp.a][0]){f[temp.a][0] = false; q[root] = element(temp.a,0,temp.step+1,head,3); root ++;}
       int tempA,tempB;
       //pour(1,2)
       if(temp.a + temp.b > b){
           tempB = b;
           tempA = temp.a + temp.b - b;
       }
       else{
           tempB = temp.a + temp.b;
           tempA = 0;
       }
       if(f[tempA][tempB]){f[tempA][tempB] = false; q[root] = element(tempA,tempB,temp.step+1,head,4); root ++;}
       //pour(2,1)
       if(temp.a + temp.b > a){
           tempA = a;
           tempB = temp.a + temp.b - a;
       }
       else{
           tempA = temp.a + temp.b;
           tempB = 0;
       }
       if(f[tempA][tempB]){f[tempA][tempB] = false; q[root] = element(tempA,tempB,temp.step+1,head,5); root ++;}
       head ++;
    }
    if(head == root){
        cout << "impossible" << endl;
        return 0;
    }
    int t = head;
    while(t > 0){
        ans[q[t].step] = q[t].operation;
        t = q[t].before;
    }
    cout << q[head].step << endl;
    for(int i = 1; i <= q[head].step; i ++){
        cout << s[ans[i]] << endl;;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值