POJ - 3414 Pots (bfs)

题意:给你两个瓶子,容量为a,b, 然后给你3种操作:(1) FILL()//装满瓶1或者瓶2 (2) DROP() //倒完瓶1或瓶2中的水 (3)POUR(i,j) //将i瓶中的水倒到j瓶中,倒满可以有剩余

思路: bfs,相对于递归的写法我还是更喜欢用队列来写。还是按照bfs的标准,递归边界,vis[]数组,终止条件。然后关于路径输出,我记录每一次成功访问状态的前一个状态,然后用stack逆向记录这样就可以正向输出了。

这个代码真的写的烂...虽然过了

完整代码:

#include <iostream>
#include <cstring>
#include <queue>
#include <stack>
using namespace std;
const int maxn = 1e5;
int num;
int flag ;

struct pot{
    int x,y;
    int prex,prey;
    int vx,vy;
    int path;
    int cnt;
};
char s[][15] ={"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"} ;
int vis[105][105];//要有一个记忆数组避免重搜 
int top;
pot fun(pot p,int opt){
    pot q;
    switch(opt){
        case 0:{
            //fill(1)
            q = p;
            q.cnt++,q.x = q.vx,q.prex = p.x,q.prey = p.y;
            vis[p.x][p.y] = 1;
            q.path=0;
            break;
        }
        case 1:{
            //fill(2)
            q = p;
            q.cnt++,q.y = q.vy,q.prex = p.x,q.prey = p.y;
            vis[p.x][p.y] = 1;
            q.path=1;
            break;
        }
        case 2:{
            //DROP(1)
            q = p;
            q.cnt++,q.x = 0,q.prex = p.x,q.prey = p.y;
            vis[p.x][p.y] = 1;
            q.path= 2; 
            break;
        }
        case 3:{
            //DROP(2)
            q = p;
            q.cnt++,q.y = 0,q.prex = p.x,q.prey = p.y;
            vis[p.x][p.y] = 1;
            q.path= 3; 
            break;
        }
        case 4:{
            //POUR(1,2)
            q = p;
            q.prex = p.x,q.prey = p.y;
            q.cnt++;
            if(q.x>(q.vy-q.y)) {//不能转换完 
                q.x -=  (q.vy-q.y);
                q.y = q.vy;
                
            }else{
                q.y += q.x;
                q.x = 0;
            
            }
            q.path=4;
            vis[p.x][p.y] = 1;
            break;
        }
        case 5:{
            q = p;
            q.prex = p.x,q.prey = p.y;
            q.cnt++;
            if(q.y>(q.vx-q.x)) {//不能转换完 
                q.y -=  (q.vx-q.x);//先减 
                q.x = q.vx;    
            }else{
                q.x += q.y;//先加后清空 
                q.y = 0;            
            }
            q.path=5;
            vis[p.x][p.y] = 1;
            break;
        }    
    }
    return q;    
}
void bfs(pot p){
    bool flag = false; 
    queue<pot> P;
    stack<pot> V;
    stack<int> ans;
    V.push(p);
    P.push(p);
    while(P.size()){
        pot q = P.front();
        V.push(q); 
        P.pop();
        for(int i=0;i<6;i++){
            pot tmp = fun(q,i);
            if(tmp.x==num||tmp.y==num) {
                cout<<tmp.cnt<<endl; 
                flag = true;//说明有找到的 
                ans.push(tmp.path);
                 while(1){
                     pot a = V.top();
                     if(a.prex==-1&&a.prey==-1) break;
                     V.pop();
                     if(a.x==tmp.prex&&a.y==tmp.prey){//前继路径 
                         ans.push(a.path);    
                         tmp = a;
                    }
                 }
                 while(ans.size()){
                    int k = ans.top();
                    ans.pop();
                    cout<<s[k]<<endl;
                 }             
                break;
            }
            if(vis[tmp.x][tmp.y]) continue;
            else P.push(tmp);
        }
        if(flag) break;
    }
    if(!flag) cout<<"impossible"<<endl;
} 
int main(){
    int a,b,c;
    while(cin>>a>>b>>c){
        num = c;
        top = 0;
        flag  =0;
        memset(vis,0,sizeof(vis));
        pot p;
        p.vx = a,p.vy = b;
        p.x = p.y = p.cnt = 0;
        p.prex = p.prey = -1;
        bfs(p);

    }
}

猜你喜欢

转载自www.cnblogs.com/Tianwell/p/11260891.html
今日推荐