POJ1606

来源:互联网 发布:js正则表达式可有可无 编辑:程序博客网 时间:2024/06/04 00:43

摘要:BFS+用set<string>来排重。

 

#include <iostream>
#include <stack>
#include <queue>
#include <set>
#include <string>
using namespace std;

typedef struct Node{
    int op;
    int a;
    int b;
    Node *pre;
}Node;

int goal = 0;
int ca = 0;
int cb = 0;
queue<Node *> q;
set<string> state;

void operation(int i, Node & node)
{
    const int buf_a = node.a;
    const int buf_b = node.b;   
    switch( i ){
        //fill a   
        case 1:
            node.a = ca;
            break;
        //fill b
        case 2:
            node.b = cb;
            break;
        //empty a
        case 3:
            node.a = 0;
            break;
        //empty b
        case 4:
            node.b = 0;
            break;
        //a->b
        case 5:
            node.b = min(cb, buf_a+buf_b);
            node.a = max(0, buf_a-(cb-buf_b));
            break;
        //b->a
        case 6:
            node.a = min(ca, buf_a+buf_b);
            node.b = max(0, buf_b-(ca-buf_a));
            break;
        default:
            break;
    }   
}

bool checkAndInsertState(Node & node)
{
    string str;   
    char buf1[10];
    sprintf(buf1, "%d", node.a);
    str = buf1;
    str += ":";
    char buf2[10];
    sprintf(buf2, "%d", node.b);
    str += buf2;
   
    if(state.find(str) != state.end()){
        return false;
    }
   
    state.insert(str);
    return true;
}

void displayOperation(int i)
{
    switch( i ){
        case 1:
            cout << "fill A" << endl;
            break;
        case 2:
            cout << "fill B" << endl;
            break;
        case 3:
            cout << "empty A" << endl;
            break;
        case 4:
            cout << "empty B" << endl;
            break;
        case 5:
            cout << "pour A B" << endl;
            break;
        case 6:
            cout << "pour B A" << endl;
            break;
        default:
            break;
    }
}

void BFS()
{
    Node * next = NULL;
   
    Node * current = new Node;
    current->pre = NULL;
    current->a = 0;
    current->b = 0;
    current->op = 0;
   
    bool find = false;   
    while( true ){
        for(int i=1; i<=6; i++){
            next = new Node;
            next->a = current->a;
            next->b = current->b;
            next->pre = current;
            next->op = i;
            operation(i, *next);
            if( next->b == goal ){
                find = true;   
                break;
            }
            if( checkAndInsertState(*next) ){
                q.push(next);
            }else{
                delete next;
            }
        }

        if( find ){
            break;
        }   
        if( q.empty() ){
            break;
        }
        current = q.front();
        q.pop();
    }

    if( find ){
        stack<int> path;
        Node *pre = next;
        while(pre!=NULL && pre->op!=0){
            path.push(pre->op);
            pre = pre->pre;
        }       
       
        while( !path.empty() ){
            int op = path.top();
            displayOperation(op);
            path.pop();   
        }
        cout << "success" << endl;
    }
}

int main()
{
    while( cin >> ca >> cb >> goal){
        state.clear();
        while( !q.empty() ){
            q.pop();
        }
        BFS();
    }

    return 0;
}