如题:http://poj.org/problem?id=3414
题目要求输入3个数A,B,C,分别代表第一个杯子可以装水的容量A,第二个杯子可以装水的容量B,要求输出通过6种操作,是否而已让2个杯子中出现C升水。
给出6种操作。"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"。
要求输出最少步数,和每一步执行的操作,如果无法完成,输出impossible。
这一题步数输出就是BFS最短路算法,每一步的下一层就是6种操作执行后的状态。
难点是对每一步的操作的输出需要记录。我使用了3个数组。f[x][y]=上一层x*100+上一层y,记录当前状态(x,y)上一层的横纵坐标,取出时只需fa[x][y]/100,fa[x][y]%100。
然后用stats[x][y]数组记录状态(1,,2,3,4,5,,6)。char str[6][10]={"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};在递归输出时用stats数组的值作为下标输出。
注意:题目没说,但其实是多组数据。
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
int vis[102][102];
short A,B,C;
char str[6][10]={"FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)"};
int f[102][102];
short stats[102][102];
void print(int a,int b)
{
if(f[a][b]==-1)
return;
int ta=f[a][b]/100;
int tb=f[a][b]%100;
print(ta,tb);
printf("%s\n",str[stats[a][b]-1]);
}
struct node
{
short a,b;
int step;
};
int final_a,final_b;
int BFS(int a,int b)
{
memset(vis,0,sizeof(vis));
memset(f,0,sizeof(f));
memset(stats,0,sizeof(stats));
node u;
u.a=a;
u.b=b;
u.step=0;
f[u.a][u.b]=-1;
vis[u.a][u.b]=1;
queue<node>q;
q.push(u);
node v;
while(!q.empty())
{
u=q.front();
if(u.a==C||u.b==C)
{
final_a=u.a;
final_b=u.b;
return u.step;
}
q.pop();
if(u.a!=A) //装满a
{
v.a=A;
v.b=u.b;
v.step=u.step+1;
if(!vis[v.a][v.b])
{
q.push(v);
vis[v.a][v.b]=1;
f[v.a][v.b]=u.a*100+u.b;
stats[v.a][v.b]=1;
}
}
if(u.b!=B) //装满b
{
v.a=u.a;
v.b=B;
v.step=u.step+1;
if(!vis[v.a][v.b])
{
q.push(v);
vis[v.a][v.b]=1;
f[v.a][v.b]=u.a*100+u.b;
stats[v.a][v.b]=2;
}
}
if(u.a!=0) //清空a
{
v.a=0;
v.b=u.b;
v.step=u.step+1;
if(!vis[v.a][v.b])
{
q.push(v);
vis[v.a][v.b]=1;
f[v.a][v.b]=u.a*100+u.b;
stats[v.a][v.b]=3;
}
}
if(u.b!=0) //清空b
{
v.a=u.a;
v.b=0;
v.step=u.step+1;
if(!vis[v.a][v.b])
{
q.push(v);
vis[v.a][v.b]=1;
f[v.a][v.b]=u.a*100+u.b;
stats[v.a][v.b]=4;
}
}
if(u.a!=0&&u.b!=B) //pour(a,b)
{
if(B-u.b>=u.a)
{
v.a=0;
v.b=u.b+u.a;
}
else
{
v.b=B;
v.a=u.a-(B-u.b);
}
v.step=u.step+1;
if(!vis[v.a][v.b])
{
q.push(v);
vis[v.a][v.b]=1;
f[v.a][v.b]=u.a*100+u.b;
stats[v.a][v.b]=5;
}
}
if(u.b!=0&&u.a!=A) //pour(b,a)
{
if(A-u.a>=u.b)
{
v.b=0;
v.a=u.a+u.b;
}
else
{
v.a=A;
v.b=u.b-(A-u.a);
}
v.step=u.step+1;
if(!vis[v.a][v.b])
{
q.push(v);
vis[v.a][v.b]=1;
f[v.a][v.b]=u.a*100+u.b;
stats[v.a][v.b]=6;
}
}
}
return -1;
}
int main()
{
while(~scanf("%d %d %d",&A,&B,&C))
{
int count=BFS(0,0);
if(count==-1)
printf("impossible\n");
else
{
printf("%d\n",count);
print(final_a,final_b);
}
}
return 0;
}