POJ ——3414 pots BFS+路径回溯(记录路径)
题目链接:http://poj.org/problem?id=3414
题意:
给你两个体积分别为A和B桶,你有三个可选择操作的方式:
1.可以将任意两个桶的其中一个在水龙头上装满水。
2.可以将任意两个桶的其中一个桶的水全部倒出来。
3.可以将桶1的水倒入桶2,直至桶1的水全部倒完 或者 桶2已全部装满水。反向操作也可以。
最终结果:
如果可以进行n次操作使得其中一个桶的容水量为C输出最少操作数目,并打印操作步骤;
反之,输出 “impossible”。
思路:
用广搜找到最短的那条路径,然后记录路径输出即可。
ac代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
const int maxn=1005;
int vis[maxn][maxn];
struct pot{
int aa,bb,dist,per,vis,vv; //代表现在两个水桶的状况,aa是桶1的水量,bb是桶2的水量
}p[100005]; //dist是到这样的情况需操作的数目,per是这一步的上一步(回溯会用 )
void show(int x){ //vis是数组的下标,vv是使用什么操作。
stack<int>s;
for(int i=x;i!=-1;i=p[i].per){
//cout<<p[i].per<<endl;
s.push(p[i].vv); //放到栈里面吗再输出。
}
while(!s.empty()){
if(s.top()==0)printf("FILL(1)\n");
if(s.top()==1)printf("FILL(2)\n");
if(s.top()==2)printf("DROP(1)\n");
if(s.top()==3)printf("DROP(2)\n");
if(s.top()==4)printf("POUR(1,2)\n");
if(s.top()==5)printf("POUR(2,1)\n");
s.pop();
}
}
void bfs(int x,int y,int a,int b,int c){
int flag=0;
int cnt=1;
memset(vis,0,sizeof(vis));
queue<pot>q;
p[0].aa=0;p[0].bb=0;p[0].per=-1;p[0].dist=0;p[0].vis=0;p[0].vv=-1;
q.push(p[0]);
vis[p[0].aa][p[0].bb]=1;
while(!q.empty()){
pot now=q.front();
q.pop();
if(now.aa==c||now.bb==c){
flag=1;
printf("%d\n",now.dist);
show(now.vis); //输出操作。
break;
}
for(int i=0;i<6;i++){
cnt++;
if(i==0){
p[cnt].aa=a;
p[cnt].bb=now.bb;
}
if(i==1){
p[cnt].aa=now.aa;
p[cnt].bb=b;
}
if(i==2){
p[cnt].aa=0;
p[cnt].bb=now.bb;
}
if(i==3){
p[cnt].aa=now.aa;
p[cnt].bb=0;
}
if(i==4){
if(now.aa+now.bb<=b){
p[cnt].aa=0;
p[cnt].bb=now.aa+now.bb;
}
else{
p[cnt].aa=(now.aa+now.bb)-b;
p[cnt].bb=b;
}
}
if(i==5){
if(now.aa+now.bb<=a){
p[cnt].aa=now.aa+now.bb;
p[cnt].bb=0;
}
else{
p[cnt].aa=a;
p[cnt].bb=(now.aa+now.bb)-a;
}
}
if(!vis[p[cnt].aa][p[cnt].bb]&&p[cnt].aa>=0&&p[cnt].aa<=a&&p[cnt].bb<=b&&p[cnt].bb>=0){
p[cnt].dist=now.dist+1;
p[cnt].per=now.vis;
p[cnt].vis=cnt;
p[cnt].vv=i;
q.push(p[cnt]);
vis[p[cnt].aa][p[cnt].bb]=1;
}
}
}
if(!flag)
printf("impossible\n");
}
int main()
{
int A,B,C;
scanf("%d%d%d",&A,&B,&C);
bfs(0,0,A,B,C);
return 0;
}