题意:有1,2两个杯子,你需要对杯子进行操作,操作包括fill填满,pour(1,2)将1倒入2种或反过来,drop倒出所有水。求出使两个杯子中出现指定量C的水需要多少步操作,并且输出操作步骤
思路:BFS对六种操作进行搜索,和以往不同的需要在结构体里加一个数组来记录操作(本人用1-6编号进行记录)。输出时对应记录输出步骤即可。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <map>
#include <string>
#define INF 0x3f3f3f3f
#define mod 1000000007
using namespace std;
struct node
{
int com[400];
int a,b;
int step;
}now,next,turn;
int vis[102][102];
int BFS(int topa,int topb,int c)
{
queue<node>Q;
turn.a=0;
turn.b=0;
turn.step=0;
Q.push(turn);
while(!Q.empty())
{
now=Q.front();
Q.pop();
for (int i=1;i<=6;i++)
{
next=now;
if(i==1) //fill(1)
next.a=topa,next.b=now.b;
else if(i==2) //fill(2)
next.b=topb,next.a=now.a;
else if(i==3) //pour(1,2)
{
next.b = now.a+now.b;
if(next.b>topb)
{
next.a=next.b-topb;
next.b = topb;
}
else
next.a=0;
}
else if(i==4) //pour(2,1)
{
next.a = now.a+now.b;
if(next.a>topa)
{
next.b=next.a-topa;
next.a = topa;
}
else
next.b=0;
}
else if(i==5) //drop(1)
next.a=0,next.b=now.b;
else if(i==6) //drop(2)
next.b=0,next.a=now.a;
next.step=now.step+1;
next.com[next.step]=i;
if(next.a==c||next.b==c)
{
return 1;
}
if(!vis[next.a][next.b])
{
vis[next.a][next.b]=1;
Q.push(next);
}
}
}
return 0;
}
int main()
{
int a,b,c;
memset(vis,0,sizeof(vis));
scanf("%d%d%d",&a,&b,&c);
if(BFS(a,b,c))
{
printf("%d\n",next.step);
for (int i=1;i<=next.step;i++)
{
switch(next.com[i])
{
case 1:printf("FILL(1)\n");break;
case 2:printf("FILL(2)\n");break;
case 3:printf("POUR(1,2)\n");break;
case 4:printf("POUR(2,1)\n");break;
case 5:printf("DROP(1)\n");break;
case 6:printf("DROP(2)\n");break;
}
}
}
else
printf("impossible\n");
return 0;
}