1. 程式人生 > >POJ-3414

POJ-3414

這只是一道記錄狀態的步驟多一點的bfs罷了。

每一步都最多有六種下一步:

1.清空A,  2.清空B  3.裝滿A  4.裝滿B  5.將A中液體倒入B  6.將B中液體倒入A;

//step[][]陣列用來記錄步數

 

//Node gogo[][]用來記載每一步具體是幹什麼的;

比如:父狀態是:      a: 0 b: 0

將設子狀態是裝滿B則子狀態為na: 0 nb: B nc: 4(對應狀態編號)

那麼gogo[na][nb]=Node(a,a,nc);

也就是每一次這一步的gogo都存了上一步的狀態,以及到達這一步需要的操作;

 

可以根據下標關係找到這一狀態的上一次狀態,於是想到可以遍歷到最後合適的結果時,將到這一步之前的狀態壓入棧,再遍歷一次即是答案;

我給出題目的樣例的bfs過程,還有註釋的地方可以知道遍歷完畢後所有的狀態;

每一步都是當前狀態的AB杯的液體量,以及操作的由來:(我旋轉不了影象。。。)

 

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<stack>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const double epos=1e-8;
const int maxn=109;

struct Node{
    int a,b;
    int c;
}tan1,in;

ostream& operator <<(ostream& os,const Node& x){
        os <<x.a<<"+"<<x.b<<"+"<<x.c<<"  ";
        return os;
    }

int A,B,C;
int step[maxn][maxn];
int flag[maxn][maxn];
Node gogo[maxn][maxn];

/*
1 FILL(1)
2 FILL(2)
3 DROP(1)
4 DROP(2)
5 POUR(1,2)
6 POUR(2,1)
*/

char s[8][12]={"000","FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};

void bfs(){
    memset(flag,0,sizeof(flag));
    memset(step,0,sizeof(step));
    memset(gogo,0,sizeof(gogo));
    queue<Node>q;
    in.a=in.b=in.c=0;
    flag[0][0]=1;
    q.push(in);
    while(!q.empty()){
        tan1=q.front();
        q.pop();
        if(tan1.a==C||tan1.b==C){
            printf("%d\n",step[tan1.a][tan1.b]);
//            for(int i=0;i<=A;i++){
//                for(int j=0;j<=B;j++)
//                    cout<<gogo[i][j];
//                cout<<endl;
//
//            }
            stack<int>ss;
            int i=tan1.a;
            int j=tan1.b;
            while(1){
                if(i==0&&j==0&&gogo[i][j].c==0)
                    break;
                ss.push(gogo[i][j].c);
                int t1=gogo[i][j].a;
                int t2=gogo[i][j].b;
                i=t1,j=t2;
            }
            while(!ss.empty()){
                printf("%s\n",s[ss.top()]);
                ss.pop();
            }
            return ;
        }

        //FILL(1);
        if(tan1.a<A){
            in.a=A;
            in.b=tan1.b;
            in.c=1;
            if(flag[in.a][in.b]==0){
                flag[in.a][in.b]=1;
                Node go;
                go.a=tan1.a;
                go.b=tan1.b;
                go.c=1;
                q.push(in);
                step[in.a][in.b]=step[tan1.a][tan1.b]+1;
                gogo[in.a][in.b]=go;
            }
        }

        //FILL(2);
        if(tan1.b<B){
            in.a=tan1.a;
            in.b=B;
            in.c=2;
            if(flag[in.a][in.b]==0){
                flag[in.a][in.b]=1;
                Node go;
                go.a=tan1.a;
                go.b=tan1.b;
                go.c=2;
                q.push(in);
                step[in.a][in.b]=step[tan1.a][tan1.b]+1;
                gogo[in.a][in.b]=go;
            }
        }

        //DROP(1);
        if(tan1.a>0){
            in.a=0;
            in.b=tan1.b;
            in.c=3;
            if(flag[in.a][in.b]==0){
                flag[in.a][in.b]=1;
                Node go;
                go.a=tan1.a;
                go.b=tan1.b;
                go.c=3;
                q.push(in);
                step[in.a][in.b]=step[tan1.a][tan1.b]+1;
                gogo[in.a][in.b]=go;
            }
        }

        //DROP(2);
        if(tan1.b>0){
            in.a=tan1.a;
            in.b=0;
            in.c=4;
            if(flag[in.a][in.b]==0){
                flag[in.a][in.b]=1;
                Node go;
                go.a=tan1.a;
                go.b=tan1.b;
                go.c=4;
                q.push(in);
                step[in.a][in.b]=step[tan1.a][tan1.b]+1;
                gogo[in.a][in.b]=go;
            }
        }

        //POUR(1,2);
        if(tan1.a>0&&tan1.b<B){
            if(tan1.a+tan1.b<B){
                in.b=tan1.a+tan1.b;
                in.a=0;
                in.c=5;
                if(flag[in.a][in.b]==0){
                    flag[in.a][in.b]=1;
                    Node go;
                    go.a=tan1.a;
                    go.b=tan1.b;
                    go.c=5;
                    q.push(in);
                    step[in.a][in.b]=step[tan1.a][tan1.b]+1;
                    gogo[in.a][in.b]=go;
                }
            }
            else{
                in.b=B;
                in.a=tan1.a-B+tan1.b;
                in.c=5;
                if(flag[in.a][in.b]==0){
                    flag[in.a][in.b]=1;
                    Node go;
                    go.a=tan1.a;
                    go.b=tan1.b;
                    go.c=5;
                    q.push(in);
                    step[in.a][in.b]=step[tan1.a][tan1.b]+1;
                    gogo[in.a][in.b]=go;
                }
            }
        }

        //POUR(2,1);
        if(tan1.b>0&&tan1.a<A){
            if(tan1.a+tan1.b<A){
                in.b=0;
                in.a=tan1.a+tan1.b;
                in.c=6;
                if(flag[in.a][in.b]==0){
                    flag[in.a][in.b]=1;
                    Node go;
                    go.a=tan1.a;
                    go.b=tan1.b;
                    go.c=6;
                    q.push(in);
                    step[in.a][in.b]=step[tan1.a][tan1.b]+1;
                    gogo[in.a][in.b]=go;
                }

            }
            else{
                in.a=A;
                in.b=tan1.b-A+tan1.a;
                in.c=6;
                if(flag[in.a][in.b]==0){
                    flag[in.a][in.b]=1;
                    Node go;
                    go.a=tan1.a;
                    go.b=tan1.b;
                    go.c=6;
                    q.push(in);
                    step[in.a][in.b]=step[tan1.a][tan1.b]+1;
                    gogo[in.a][in.b]=go;
                }
            }
        }
    }
    printf("impossible\n");
    return ;
}


int main(){
    scanf("%d%d%d",&A,&B,&C);
    bfs();
    return 0;
}