题目链接:https://cn.vjudge.net/contest/313994#problem/F
思路:bfs需要输出路径,不能用c++的queue,因为回溯的过程要用到队列的下标,所以我们需要模拟队列
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Maxn = 1e5+10;
int n,m,k;
int vis[110][110];
struct node
{
int a; // 第一个杯子中的水
int b; // 第二个杯子中的水
int step; //记录步数
int pre;// 记录路径,回溯
int pos; // 记录操作
} q[1100]; //模拟队列
int ans[1100]; // 记录回溯过程
void bfs()
{
struct node now;
now.a = 0;
now.b = 0;
now.step = 0;
now.pre = -1;
int head = 0;
int tail = 0;
q[tail++] = now;
vis[0][0] = 1;
while(head!=tail)
{
now = q[head];
struct node after;
if(now.a==k||now.b==k)
{
cout<<now.step<<endl;
int len = 0;
for(int i=head; i!=-1; i=q[i].pre) //将路径记录
{
ans[len++] = i;
}
for(int i=len-1; i>=0; i--) //输出路径
{
if(q[ans[i]].pos==1)
{
printf("FILL(1)\n");
}
else if(q[ans[i]].pos==2)
{
printf("FILL(2)\n");
}
else if(q[ans[i]].pos==3)
{
printf("DROP(1)\n");
}
else if(q[ans[i]].pos==4)
{
printf("DROP(2)\n");
}
else if(q[ans[i]].pos==5)
{
printf("POUR(1,2)\n");
}
else if(q[ans[i]].pos==6)
{
printf("POUR(2,1)\n");
}
}
return;
}
for(int i=0; i<6; i++) //倒水操作
{
if(i==0)
{
after.a = n;
after.b = now.b;
after.pre = head;
after.pos = 1;
}
else if(i==1)
{
after.a = now.a;
after.b = m;
after.pre = head;
after.pos = 2;
}
else if(i==2)
{
after.a = 0;
after.b = now.b;
after.pre = head;
after.pos = 3;
}
else if(i==3)
{
after.a = now.a;
after.b = 0;
after.pre = head;
after.pos = 4;
}
else if(i==4)
{
if(now.a+now.b<=m)
{
after.a = 0;
after.b = now.a + now.b;
}
else
{
after.a = now.a-(m-now.b);
after.b = m;
}
after.pre = head;
after.pos = 5;
}
else if(i==5)
{
if(now.a+now.b<=n)
{
after.b = 0;
after.a = now.a+now.b;
}
else
{
after.b = now.b-(n-now.a);
after.a = n;
}
after.pre = head;
after.pos = 6;
}
if(!vis[after.a][after.b])
{
after.step = now.step + 1;
vis[after.a][after.b] = 1;
q[tail++] = after;
}
}
head++;
}
cout<<"impossible"<<endl;
}
int main()
{
cin>>n>>m>>k;
memset(vis,0,sizeof(vis));
bfs();
return 0;
}