题目链接:
题目
题意:两个杯子倒水,凑出一杯水量为c。
题解:BFS一波,对于路径用指针记录前导状态,然后输出的时候用栈调整顺序。
收获:前导指针,栈倒序。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
int cnt=0;
struct node {
int a,b;//水量
int step;//步数
int op;//操作标记
node* pre;//前导
}now,cup[400];
int vis[105][105];
int bfs(int a,int b,int c){
queue<node> que;
now.a=0;
now.b=0;
now.step=0;
now.pre=NULL;
now.op=0;
vis[0][0]=1;
que.push(now);
int i;
while(!que.empty()){
cup[++cnt]=que.front();
node temp=cup[cnt];
vis[cup[cnt].a][cup[cnt].b]=1;
que.pop();
if(temp.a==c||temp.b==c)return temp.step;
for(i=1;i<=6;i++){
switch(i){
case 1://fill a
now.a=a;
now.b=temp.b;
break;
case 2://fill b
now.a=temp.a;
now.b=b;
break;
case 3://drop a
now.a=0;
now.b=temp.b;
break;
case 4://drop b
now.a=temp.a;
now.b=0;
break;
case 5://a(->b
if(temp.a<b-temp.b){
now.a=0;
now.b=temp.b+temp.a;
}
else {
now.a=temp.a-(b-temp.b);
now.b=b;
}
break;
case 6://b->a
if(temp.b<a-temp.a){
now.b=0;
now.a=temp.a+temp.b;
}
else {
now.b=temp.b-(a-temp.a);
now.a=a;
}
break;
}
if(vis[now.a][now.b])continue;
now.op=i;
now.pre=&cup[cnt];
now.step=cup[cnt].step+1;
que.push(now);
}
}
return -1;
}
void huishuoprint(){
stack<int > sta;
node temp=cup[cnt];
while(temp.pre){
sta.push(temp.op);
temp=*temp.pre;
}
while(!sta.empty()){
int i = sta.top();
sta.pop();
switch(i) {
case 1:cout<<"FILL(1)"<<endl;break;
case 2:cout<<"FILL(2)"<<endl;break;
case 3:cout<<"DROP(1)"<<endl;break;
case 4:cout<<"DROP(2)"<<endl;break;
case 5:cout<<"POUR(1,2)"<<endl;break;
case 6:cout<<"POUR(2,1)"<<endl;break;
}
}
return ;
}
int main()
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
int ans=bfs(a,b,c);
if(ans==-1)printf("impossible\n");
else {
printf("%d\n",ans);
huishuoprint();
}
return 0;
}