HDOJ 1495 非常可樂 【bfs】

HDOJ 1495 非常可樂 【bfs】

題目鏈接 http://acm.hdu.edu.cn/showproblem.php?pid=1495


一共只有6種狀態
a → b
a → c
b → a
b → c
c → a
c → b
bfs搜一遍即可
注意隊列清空 標記數組清零
輸入S爲奇數時一定不符合要求,刪除該情況剪枝

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int S, N, M;
typedef struct state{
    int s, n, m; // 三個杯子的容量
    int step; // 次數
}state;
queue<state> q;
bool vis[105][105][105];
bool End(int a, int b, int c){
    if((a == b && c == 0) || (a == c && b == 0) || (b == c && a == 0)){
        return true;
    }
    else
        return false;
}

int bfs(){
    memset(vis, 0, sizeof(vis));
    while(!q.empty()) q.pop();
    state start;
    start.s = S, start.n = 0, start.m = 0, start.step = 0;
    vis[S][0][0] = true;
    //printf("start\n");
    q.push(start);
    while(!q.empty()){
        state current, next;
        int s, n, m, step; // current.
        current = q.front();
        s = current.s, n = current.n, m = current.m, step = current.step;
        //printf("%d\t%d\t%d\n", s, n, m);

        if(End(s, n, m)){ // 判斷結束
            //printf("%d\n", step);
            return step;
        }

        next.step = step+1;
        if(s > 0){ // a → b / c
            if(s > N-n){ // a → b a有剩餘
                next.s = s-(N-n);
                next.n = N;
                next.m = m;
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("a → b a有剩餘\n");
                    q.push(next);
                }
            }
            else{ // a → b a無剩餘
                next.s = 0;
                next.n = n+s;
                next.m = m;
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("a → b a無剩餘\n");
                    q.push(next);
                }
            }
            if(s > M-m){ // a → c a有剩餘
                next.s = s-(M-m);
                next.n = n;
                next.m = M;
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("a → c a有剩餘\n");
                    q.push(next);
                }
            }
            else{ // a → c a無剩餘
                next.s = 0;
                next.n = n;
                next.m = m+s;
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("a → c a無剩餘\n");
                    q.push(next);
                }
            }
        }
        if(n > 0){ // b → a / c
            if(n > S-s){ // b → a b有剩餘
                next.s = S;
                next.n = n - (S-s);
                next.m = m;
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("b → a b有剩餘\n");
                    q.push(next);
                }
            }
            else{ // b → a b無剩餘
                next.s = s+n;
                next.n = 0;
                next.m = m;
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("b → a b無剩餘\n");
                    q.push(next);
                }
            }
            if(n > M-m){ // b → c b有剩餘
                next.s = s;
                next.n = n - (M-m);
                next.m = M;
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("b → c b有剩餘\n");
                    q.push(next);
                }
            }
            else{ // b → c b無剩餘
                next.s = s;
                next.n = 0;
                next.m = m+n;
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("b → c b無剩餘\n");
                    q.push(next);
                }
            }
        }
        if(m > 0){ // c → a / b
            if(m > S-s){ // c → a c有剩餘
                next.s = S;
                next.n = n;
                next.m = m - (S-s);
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("c → a c有剩餘\n");
                    q.push(next);
                }
            }
            else{ // c → a c無剩餘
                next.s = s+m;
                next.n = n;
                next.m = 0;
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("c → a c無剩餘\n");
                    q.push(next);
                }
            }
            if(m > N-n){ // c → b c有剩餘
                next.s = s;
                next.n = N;
                next.m = m - (N-n);
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("c → b c有剩餘\n");
                    q.push(next);
                }
            }
            else{ // c → b c無剩餘
                next.s = s;
                next.n = n+m;
                next.m = 0;
                if(vis[next.s][next.n][next.m] == false){
                    vis[next.s][next.n][next.m] = true;
                    //printf("c → b c無剩餘\n");
                    q.push(next);
                }
            }
        }
        q.pop();
    }
    return 0;
}

int main(){
    while(~scanf("%d%d%d", &S, &N, &M)){
        if(!S && !N && !M) break;
        if(S & 1) printf("NO\n");
        else{
            int ans = bfs();
            if(!ans) printf("NO\n");
            else printf("%d\n", ans);
        }
    }

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章