poj 3414 pots

题意: 有两个容器,一个容量为A,一个容量为B; 有三种操作:
1. FILL(i) : 给容器i装满水,i = 1 或2;
2. DROP(i ): 倒掉容器i的所有水;
3. POUR(i,j):将i中水倒入j中,直到j装满,i中可以有剩余,或者i不足以装满j;

思路: BFS 加上记忆路径,难点在打印路径。

代码很丑。。。

#include "iostream"
#include "queue"
#include "cstring"

using namespace std;


int A,B,C;
int visit[105][105];  //判断是否访问过此状态

struct Node{
    int prex;        //记录前一个状态的A容器状态
    int prey;       //记录前一个状态的B容器状态
    int x;         //x,y为此时状态
    int y;    
    int step;     //步数
    int op;       //前一状态到此状态的操作,有六种
};

Node pot[105][105]; 用于记忆路径

void output(Node s) {    //打印路径
    if(s.prex == -1 && s.prey == -1) return;

    else {
        output(pot[s.prex][s.prey]);  //递归,总是再打印前一操作后再打印后一步操作
        switch(s.op) {
             case  1:cout <<"FILL(1)\n";break;
             case  2:cout <<"FILL(2)\n";break;
             case  3:cout <<"DROP(1)\n";break;
             case  4:cout <<"DROP(2)\n";break;
             case  5:cout <<"POUR(1,2)\n";break;
             case  6:cout <<"POUR(2,1)\n";break;
             default:cout <<"something wrong\n";break;
        }

    }

}

void bfs() { //简单的宽搜
    Node s;

    s.prex = -1;
    s.prey = -1;
    s.x = 0;
    s.y = 0;
    s.step = 0;
    s.op = -1;

    memset(visit,0,sizeof(visit));

    queue<Node>q;
    while(!q.empty()) q.pop();
    q.push(s);

    while(!q.empty()) {
        s = q.front();
        q.pop();
        pot[s.x][s.y] = s;  //将此点记录下来

        if(s.x == C || s.y == C) {
            cout << s.step << endl;
            output(s);
            return;
        }

        visit[s.x][s.y] = 1;

        for(int i = 1; i <= 6; i++) { //六个操作
            if(i == 1 && !visit[A][s.y]) {
                visit[A][s.y] = 1;
                Node next;

                next.prex = s.x;
                next.prey = s.y;
                next.x = A;
                next.y = s.y;
                next.step = s.step+1;
                next.op = i;

                q.push(next);
            }

            if(i == 2 && !visit[s.x][B]) {
                visit[s.x][B] = 1;
                Node next;

                next.prex = s.x;
                next.prey = s.y;
                next.x = s.x;
                next.y = B;
                next.step = s.step+1;
                next.op = i;

                q.push(next);
            }

            if(i == 3 && !visit[0][s.y]) {
                visit[0][s.y] = 1;
                Node next;

                next.prex = s.x;
                next.prey = s.y;
                next.x = 0;
                next.y = s.y;
                next.step = s.step+1;
                next.op = i;

                q.push(next);
            }

            if(i == 4 && !visit[s.x][0]) {
                visit[s.x][0] = 1;
                Node next;

                next.prex = s.x;
                next.prey = s.y;
                next.x = s.x;
                next.y = 0;
                next.step = s.step+1;
                next.op = i;

                q.push(next);
            }

            if(i == 5 ) {
                int nx,ny;
                if(s.x + s.y > B) {
                     nx = s.x + s.y - B;
                     ny = B;
                }
                else if(s.x+s.y <= B) {
                    nx = 0;
                    ny = s.x + s.y;
                }

                if(!visit[nx][ny]) {
                    visit[nx][ny] = 1;
                    Node next;

                    next.prex = s.x;
                    next.prey = s.y;
                    next.x = nx;
                    next.y = ny;
                    next.step = s.step+1;
                    next.op = i;

                    q.push(next);
                }

            }

            if(i == 6) {
                int nx,ny;
                if(s.x + s.y > A) {
                     ny = s.x + s.y - A;
                     nx = A;
                }
                else if(s.x+s.y <= A) {
                    ny = 0;
                    nx = s.x + s.y;
                }

                 if(!visit[nx][ny]) {
                    visit[nx][ny] = 1;
                     Node next;

                    next.prex = s.x;
                    next.prey = s.y;
                    next.x = nx;
                    next.y = ny;
                    next.step = s.step+1;
                    next.op = i;
                    q.push(next);
                }
            }
        }

    }

    cout << "impossible" << endl;
    return;
}



int main() {

    while(cin >> A >> B >> C) {
        bfs();
    }


return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值