经过这道题目,加深了对bfs 以及 回溯的理解。
对于bfs 而言,重要的结点 node 的构建 ,而结点就代表着一种状态。其中包括了进行的操作,a, b 两个的容量。路径长度,要进行回溯的要就要在node 中添加一个pre 指针。
在bfs 中,关键的还是返回条件(其中一个的值与c相等就结束了,记录路程,并返回)
#include <iostream>
#include <queue>
#include <stack>
#include <memory.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;
int a,b,c,ans;
int vis[110][110];
struct node
{
int a,b;
int step;
int flag;
node *pre;
};
stack<int> sta;
queue<node> q;
void bfs()
{
node cur,map[1000];
cur.a=0;
cur.b=0;
cur.step=0;
cur.flag=0;
cur.pre=NULL;
q.push(cur);
int count=-1;
while(!q.empty() )
{
cur=q.front();
q.pop();
node next;
map[++count]=cur;
if(cur.a==c||cur.b==c)
{
ans=cur.step;
while(cur.pre!=NULL)
{
sta.push(cur.flag);
cur=*cur.pre;
}
return ;
}
for(int i=1;i<=6;i++)
{
if(i==1)
{
if(cur.a==a) continue;
next.a=a;
next.b=cur.b;
}
else if(i==2)
{ if(cur.b==b) continue;
next.b=b;
next.a=cur.a;
}
else if(i==3)
{ if(cur.a==0) continue;
next.a=0;
next.b=cur.b;
}
else if(i==4)
{
if(cur.b==0) continue;
next.a=cur.a;
next.b=0;
}
else if(i==5)
{
next.a=max(0,cur.a+cur.b-b);
next.b=min(b,cur.a+cur.b);
}
else if(i==6)
{
next.a=min(a,cur.a+cur.b);
next.b=max(0,cur.a+cur.b-a);
}
next.flag=i;
if(!vis[next.a][next.b] )
{
vis[next.a][next.b]=1;
next.step=cur.step+1;
next.pre=&map[count];
q.push(next);
}
}
}
}
int main()
{
while(cin>>a>>b>>c)
{
memset(vis,0,sizeof(vis ) );
bfs();
if(ans==0 )
{ cout<<"impossible"<<endl;
continue;
}
cout<<ans<<endl;
while(!sta.empty() )
{
int i=sta.top();
sta.pop();
if(i==1)
cout<<"FILL(1)";
else if (i==2)
cout<<"FILL(2)";
else if (i==3)
cout<<"DROP(1)";
else if (i==4)
cout<<"DROP(2)";
else if (i==5)
cout<<"POUR(1,2)";
else cout<<"POUR(2,1)";
cout<<endl;
}
}
}