POJ-3414
阿新 • • 發佈:2018-12-07
這只是一道記錄狀態的步驟多一點的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; }