#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
bool status[102][102];   //定义A,B容器中水的所有状态(由于水的容量最多到100,所以status数组光开到100是不够的!)
int A, B, C;             //定义A容器容量、B容器容量、满足的容量数
int K = 0;               //定义最小操作数K
int flag = 0;
string direction[6] = { "FILL(1)","FILL(2)","DROP(1)","DROP(2)","POUR(1,2)","POUR(2,1)" };  //定义六种操作
struct Point
{
	int Awater;          //定义A罐子的水量
	int Bwater;          //定义B罐子的水量
	int pre;             //定义该状态的上一步在队列中的下标
	int operation;       //定义执行了什么操作
} Q[10000];              //定义以数组实现的队列
void dfs(struct Point point);     //定义进行递归的函数
struct Point bfs();      //定义进行bfs的函数
struct Point bfs()
{
	int i;
	int atemp, btemp;        //定义操作完的A,B容器容量
	int now;                 //定义当前状态在数组中的下标
	Q[0].Awater = 0;         //定义刚开始状态A容器容量为0
	Q[0].Bwater = 0;         //定义刚开始状态B容器容量为0
	Q[0].pre = -1;           //定义刚开始状态的上一步下标为-1
	status[0][0] = true;     
	int front=1,j=0; //定义队列的对首和队尾指针
	while (true)
	{
		now = j;            //将当前状态在数组的下标设置为now
		if (now >= front)   //如果当前的now超过了数组当中的指针front(代表now一直遍历的都是搜索到的状态)
		{
			break;
		}
		for (i = 0; i < 6; i++)
		{
			atemp = Q[now].Awater;
			btemp = Q[now].Bwater;
			if (i == 0)
			{
				if (atemp == A)
				{
					continue;
				}
				atemp = A;  //将A容器进行倒满,B容器不做修改
			}
			else if (i == 1)
			{
				if (btemp == B)
				{
					continue;
				}
				btemp = B;  //将B容器进行倒满,A容器不做修改
			}
			else if (i == 2)
			{
				if (atemp == 0)
				{
					continue;
				}
				atemp = 0;  //将A容器进行抽干,B容器不做修改
			}
			else if (i == 3)
			{
				if (btemp == 0)
				{
					continue;
				}
				btemp = 0;  //将B容器进行抽干,A容器不做修改
			}
			else if (i == 4)
			{
				int pour = min(atemp, B - btemp);      //让A容器中水的容量和B容器中剩余的容量取最小值
				atemp -= pour;                      //从A容器中取出水
				btemp += pour;                      //让B容器接收A取出的水
				if (pour == 0)                      //如果A容器中水为空,或者B容器中没有剩余的容量,那么从A容器中倒出水给B,则两容器中的水不会做任何改变
				{
					continue;                       //若不会做任何改变就直接进行下一次操作
				}
			}
			else if (i == 5)
			{
				int pour = min(btemp, A - atemp);      //跟上述情况相反,这里就不再阐述
				btemp -= pour;
				atemp += pour;
				if (pour == 0)
				{
					continue;
				}
			}
			if (status[atemp][btemp] == false)     //若本次A,B容器中水的状态没有搜索过,那么把它加入到数组中。若加入过则搜索其它状况
			{
				Q[front].Awater = atemp;           //A容器容量赋值
				Q[front].Bwater = btemp;           //B容器容量赋值
				Q[front].pre = now;                //记录移动后状态的上一个状态在数组中的下标(now)
				Q[front].operation = i;            //记录操作
				status[atemp][btemp] = true;
				front++;                           //将数组下标+1
			}
			if (Q[now].Awater == C || Q[now].Bwater == C)  //如果搜索的状态中A容器或B容器中的容量到了满足的容量数,那么就进行退出
			{
				return Q[now];
			}
		}
		j++;
	}
	struct Point bad;
	bad.pre = -10000;
	return bad;                                   //如果没有符合的容量数,直接退出
}
void dfs(struct Point point)
{
	if (point.pre != -1)
	{
		K++;
	}
	if (point.pre == -10000)
	{
		cout << "impossible" << endl;
		return;
	}
	if (point.pre == -1)                             //如果递归到了初始状态(两容器水都为0时)
	{
		return;
	}
	dfs(Q[point.pre]);
	if (flag == 0)
	{
		cout << K << endl;
		flag = 1;
	}
	cout << direction[point.operation] << endl;
}
int main()
{
	struct Point end_point;    
	scanf("%d %d %d", &A, &B, &C);
	end_point = bfs();
	dfs(end_point);
}
原文:https://www.cnblogs.com/gao79135/p/14088520.html