水壶(广度优先遍历) - C ++

时间:2016-04-22 02:44:24

标签: c++ breadth-first-search

#include <iostream>
#include <queue>
using namespace std;

int a,b,c;

class State{
    public:
        int x,y,steps;
        State(){
            x = 0;
            y = 0;
            steps = 0;
        }
};

int gcd(int a, int b){
    if(a == 0){
        return b;
    }
    if(b == 0){
        return a;
    }
    else if(a > b){
        gcd(a%b,b);
    }
    else if(b > a){
        gcd(a,b%a);
    }
}

int bfs(){
    queue<State> q;
    bool visited[a+1][b+1] = {0};
    //Start from (0,0)
    State curr = State();
    q.push(curr);
    visited[curr.x][curr.y] = true;
    //Start bfs
    while(!q.empty()){
        curr = q.front();
        q.pop();
        //Goal is reached
        if(curr.x == c || curr.y == c){
            cout<<curr.x<<" "<<curr.y<<endl;
            visited[curr.x][curr.y] = true;
            return curr.steps;
        }
        //Fill up a
        if(curr.x < a){
            State newState = State();
            newState.x = a;
            newState.y = curr.y;
            if(!visited[newState.x][newState.y]){
                newState.steps = curr.steps + 1;
                q.push(newState);
                visited[newState.x][newState.y] = true;
            }
        }
        //Fill up second jug
        if(curr.y < b){
            State newState = State();
            newState.x = curr.x;
            newState.y = b;
            if(!visited[newState.x][newState.y]){
                newState.steps = curr.steps + 1;
                q.push(newState);
                visited[newState.x][newState.y] = true;
            }
        }
        //Empty first jug
        if(curr.x > 0){
            State newState = State();
            newState.x = 0;
            newState.y = curr.y;
            if(!visited[newState.x][newState.y]){
                newState.steps = curr.steps + 1;
                q.push(newState);
                visited[newState.x][newState.y] = true;
            }
        }
        //Empty second jug
        if(curr.y > 0){
            State newState = State();
            newState.x = curr.x;
            newState.y = 0;
            if(!visited[newState.x][newState.y]){
                newState.steps = curr.steps + 1;
                q.push(newState);
                visited[newState.x][newState.y] = true;
            }
        }
        //Pour first jug into second
        if(curr.x > 0 && curr.y < b){
            State newState = State();
            newState.x = max(0, curr.x + curr.y - b);
            newState.y = min(curr.x + curr.y, b);
            if(!visited[newState.x][newState.y]){
                newState.steps = curr.steps + 1;
                q.push(newState);
                visited[newState.x][newState.y] = true;
            }
        }
        //Pour second jug into first
        if(curr.y > 0 && curr.x < a){
            State newState = State();
            newState.x = min(a, curr.x + curr.y);
            newState.y = max(0, curr.x + curr.y - a);
            if(!visited[newState.x][newState.y]){
                newState.steps = curr.steps + 1;
                q.push(newState);
                visited[newState.x][newState.y] = true;
            }
        }
    }
}

int main() {
    int t;
    cin>>t;
    for(int testcase=0; testcase<t; testcase++){
        cin>>a>>b>>c;
        //If c is a multiple of gcd(a,b) then it is solvable
        if(c % gcd(a,b) == 0 && c <= max(a,b)){
            cout<<bfs()<<endl;
        }
        else{
            cout<<-1<<endl;
        }
    }
    return 0;
}

我正在尝试使用bfs解决两个水壶问题。 我正在使用以下生产规则,从一个州迁移到另一个州,

(x,y) - &gt; (a,y)如果x&lt; a,如果第一个罐子尚未满,则填充第一个罐子 (x,y) - &gt; (x,b)如果y < b,如果第二个罐子尚未满,则填充第二个罐子 (x,y) - &gt; (0,y)如果x> 0即,清空第一个水罐
(x,y) - &gt; (x,0)如果y> 0即,清空第二个水壶
(x,y) - &gt; (min(x + y,a),max(0,x + y -a))如果y> 0,即,从第二个罐子倒入第一个罐子直到第一个罐子装满或第二个罐子是空的 (x,y) - &gt; (max(0,x + y-b),min(x + y,b))如果x> 0,即从第一个水壶倒入第二个水壶,直到第二个水壶装满或第一个水壶是空的

要清楚,
第一壶容量= a
第二个容器的容量= b
目标水量= c

对于测试用例,a = 5,b = 2,c = 3,我得到正确答案,即2。 对于测试用例,a = 10,b = 7,c = 6,我得到0.但正确的答案是6。

0 个答案:

没有答案