NYOJ21 三個水杯 (經典問題 bfs)

NYOJ21 三個水杯 (經典問題 bfs)

2014年12月21日 22:26:46

閱讀數:1278

題目描述:
轉載地址https://blog.csdn.net/fool_ran/article/details/42065653

給出三個水杯,大小不一,並且只有最大的水杯的水是裝滿的,其餘兩個爲空杯子。三個水杯之間相互倒水,並且水杯沒有標識,只能根據給出的水杯體積來計算。現在要求你寫出一個程序,使其輸出使初始狀態到達目標狀態的最少次數。

輸入

第一行一個整數N(0<N<50)表示N組測試數據
接下來每組測試數據有兩行,第一行給出三個整數V1 V2 V3 (V1>V2>V3 V1<100 V3>0)表示三個水杯的體積。
第二行給出三個整數E1 E2 E3 (體積小於等於相應水杯體積)表示我們需要的最終狀態

輸出

每行輸出相應測試數據最少的倒水次數。如果達不到目標狀態輸出-1

樣例輸入

2
6 3 1
4 1 1
9 3 2
7 1 1

樣例輸出

3
-1

 

題目分析:

經典題目,bfs搜索,不用回溯,直接暴力即可。

AC代碼:

 


 
  1.  
    /**
     *bfs,隱式圖的搜索
     */
    #include<iostream>
    #include<cstdio>
    #include<map>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<cstdlib>
    #include<cctype>
    #include<cstring>
    #include<cmath>
    using namespace std;
    int vis[101][101][101];//記錄是否被訪問
    struct StateNode{
        int cur[3];//記錄當前狀態
        int v[3];//記錄狀態
        int step;//步數
    };
    queue<StateNode> q;
    int Sucess(StateNode a,StateNode b){//比較是否相等
        return (a.cur[0] == b.cur[0] && a.cur[1] == b.cur[1] && a.cur[2] == b.cur[2]);
    }
    int main()
    {
        int t,res;
        StateNode b,e;
        cin>>t;
        while(t--){
            res=-1;
            while(!q.empty()){//清空隊列
                q.pop();
            }
            cin>>b.v[0]>>b.v[1]>>b.v[2];
            //下面開始模擬倒水,並搜索
            b.cur[0]=b.v[0];//首先先給最大的水杯倒滿水
            b.cur[1]=b.cur[2]=0;//小杯子爲0
            b.step=0;//記錄步數
     
            cin>>e.cur[0]>>e.cur[1]>>e.cur[2];
     
            int ok=0;//記錄是否可以到達結尾狀態
            memset(vis,0,sizeof(vis));
            q.push(b);//加入隊列
            vis[b.cur[0]][b.cur[1]][b.cur[2]]=1;//已經在訪問或者已經訪問
            while(!q.empty()){//進行廣搜
                StateNode u=q.front();
                //cout<<u.cur[0]<<" "<<u.cur[1]<<" "<<u.cur[2]<<endl;
                q.pop();
                if(Sucess(u,e)){//成功並結束
                    res=u.step;
                    break;
                }
                //else 模擬倒水
                for(int i=0;i<=2;i++){//用每一個被子給其他兩個被子倒水
                    for(int j=0;j<=2;j++){
                        if(i!=j){
                            int minv=u.v[j]-u.cur[j];//從當前狀態到被子倒滿,需要的水
                            if(u.cur[i]<minv){//當前的水小於需要的水,則能用的水變爲當前的水
                                minv=u.cur[i];
                            }
                            //出現新節點
                            StateNode v=u;
                            v.cur[i]-=minv;//必須先減去
                            v.cur[j]+=minv;
                            v.step=u.step+1;//更新步數
                            //cout<<u.step<<endl;
                            if(!vis[v.cur[0]][v.cur[1]][v.cur[2]]){//該結點沒有被訪問
                                q.push(v);//加入隊列
                                vis[v.cur[0]][v.cur[1]][v.cur[2]]=1;//已訪問
                            }
                        }
                    }
                }
     
            }
            cout<<res<<endl;
        }
    	return 0;
    }
    

     

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