1. 程式人生 > >poj 3414 bfs 兩個壺倒水,記錄路徑

poj 3414 bfs 兩個壺倒水,記錄路徑

題意:給你兩個壺,容量分別為a,b,初始都是0,再給你一個目標水量c,問經過幾次操作可以使得其中一個壺的水量為目標水量c,並且把操作步驟輸出。

6個操作:

1、FILL(1)//FILL(i),把 i 壺裝滿

2、FILL(2)

3、DROP(1)//DROP(i),把 i 壺倒光

4、DROP(2)

5、POUR(1,2)//POUR(i,j)從 i 壺裡倒水到 j 壺,直至 i 壺空了,或者 j 壺滿了

6、POUR(2,1)

bfs最短路,關鍵點:

佇列元素:兩個壺的水量、在佇列裡的位置、上一個操作在佇列裡的位置、達到這個水量的操作(這三步是為了記錄路徑)

程式碼:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int ms = 3e6;
struct node{
    int a,b;  
    int index;
    int way;
    int last;
};

node queue[ms];
int front,rear,visit[105][105] = {0},path[ms];

void Init(){
    front = rear = 0;
}

bool IsEmpty(){
    if(front == rear)
        return true;
    return false;
}

void Push(node x){
    if(visit[x.a][x.b])
        return;
    visit[x.a][x.b] = 1;
    x.index = rear;
    queue[rear++] = x;
    return;
}

void Pop(){
    front++;
    return;
}

void Print(int w){
    if(w == 1){
        printf("FILL(1)\n");
        return;
    }

    if(w == 2){
        printf("FILL(2)\n");
        return;
    }

    if(w == 3){
        printf("DROP(1)\n");
        return;
    }

    if(w == 4){
        printf("DROP(2)\n");
        return;
    }

    if(w == 5){
        printf("POUR(1,2)\n");
        return;
    }

    if(w == 6){
        printf("POUR(2,1)\n");
        return;
    }
    return;
}

int main(){
    int m1,m2,c,k;
    
    while(scanf("%d %d %d",&m1,&m2,&c) != EOF){
        k = -1;
        
        Init();
        node start;
        start.a = start.b = 0;
        start.index = 0;
        start.last = -1;
        start.way = -1;
        queue[0] = start;
        rear = 1;
        visit[0][0] = 1; 

        while(!IsEmpty()){
            node top = queue[front];
            Pop();
            if(top.a ==c || top.b ==c){
                int pos = top.index;
                
                while(queue[pos].way != -1){
                    path[++k] = queue[pos].way;
                    pos = queue[pos].last;
                }
                
                printf("%d\n",k+1);

                while(k >= 0){
                    Print(path[k]);
                    k--;
                }
                k = 0;
                break;
            }

            node newn;
            newn.last = top.index;
            //FILL(1) = 1;
            newn.a = m1;
            newn.b = top.b;
            newn.way = 1;
            Push(newn);

            //FILL(2) = 2;
            newn.a = top.a;
            newn.b = m2;
            newn.way = 2;
            Push(newn);

            //DROP(1) = 3;
            newn.a = 0;
            newn.b = top.b;
            newn.way = 3;
            Push(newn);

            //DROP(2) = 4;
            newn.a = top.a;
            newn.b = 0;
            newn.way = 4;
            Push(newn);

            //POUR(1,2) = 5;
            int tmp = m2 - top.b;
            if(tmp <= top.a){
                newn.a = top.a - tmp;
                newn.b = m2;
            }
            else{
                newn.a = 0;
                newn.b = top.b + top.a;
            }
            newn.way = 5;
            Push(newn);

            //POUR(2,1) = 6;
            tmp = m1 - top.a;
            if(tmp <= top.b){
                newn.a = m1;
                newn.b = top.b - tmp;
            }
            else{
                newn.a = top.a + top.b;
                newn.b = 0;
            }
            newn.way = 6;
            Push(newn);

        }

        if(k == -1)
            printf("impossible\n");

    }
}