一、内容

给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作
FILL(i) 将第i个容器从水龙头里装满(1 ≤ i ≤ 2);
DROP(i) 将第i个容器抽干
POUR(i,j) 将第i个容器里的水倒入第j个容器(这次操作结束后产生两种结果,一是第j个容器倒满并且第i个容器依旧有剩余,二是第i个容器里的水全部倒入j中,第i个容器为空)
现在要求你写一个程序,来找出能使其中任何一个容器里的水恰好有C升,找出最少操作数并给出操作过程
Input

有且只有一行,包含3个数A,B,C(1<=A,B<=100,C<=max(A,B))

Output
第一行包含一个数表示最小操作数K
随后K行每行给出一次具体操作,如果有多种答案符合最小操作数,输出他们中的任意一种操作过程,如果你不能使两个容器中的任意一个满足恰好C升的话,输出“impossible”
Sample Input

3 5 4

Sample Output

6
FILL(2)
POUR(2,1)
DROP(1)
POUR(2,1)
FILL(2)
POUR(2,1)

二、思路

  • 用vis数组记录该状态是否被访问过,vis[a][b]表示第一个pot的体积为a,第二个的pot的体积为b。
  • 结构体string保存路径,最后输出一下就行。

三、代码

#include <cstdio>
#include <string>
#include <cstring>
#include <queue> 
#include <iostream>
using namespace std;
struct node {
	int a, b, step;
	string opt;
	node(int a, int b, string opt, int step): a(a), b(b), opt(opt), step(step){}
};
int a, b, c, vis[105][105];

string bfs() {
	queue<node> q;
	q.push(node(0, 0, "", 0));
	vis[0][0] = 1;//表示a为0 b也为0 
	while (q.size()) { 
		node t = q.front();
		q.pop();
		if (t.a == c || t.b == c) {
			cout << t.step << endl;
			return t.opt;
		} 
		//3种操作
		//第一种操作Fill
		if (!vis[a][t.b]) {
			//将a装满
			vis[a][t.b] = 1;
			q.push(node(a, t.b, t.opt + "FILL(1)\n", t.step + 1)); 
		}
		if (!vis[t.a][b]) {
			//将a装满
			vis[t.a][b] = 1;
			q.push(node(t.a, b, t.opt + "FILL(2)\n", t.step + 1)); 
		}							 
		//第二种操作将a空 或者将b空
		if (t.a != 0 && !vis[0][t.b]) {
			vis[0][t.b] = 1;
			q.push(node(0, t.b, t.opt + "DROP(1)\n", t.step + 1)); 
		} 
		if (t.b != 0 && !vis[t.a][0]) {
			vis[t.a][0] = 1;
			q.push(node(t.a, 0, t.opt + "DROP(2)\n", t.step + 1)); 
		}		
		//第三种操作 将i to j 
		if (t.a != 0 && t.b != b) {
			int cha = b - t.b;
			if (cha >= t.a) {
				//将a全部导入b
				if (!vis[0][t.b + t.a]) {
					vis[0][t.b + t.a] = 1;
					q.push(node(0, t.b + t.a, t.opt + "POUR(1,2)\n", t.step + 1));
				} 
			} else {
				if (!vis[t.a - cha][b]) {
					vis[t.a - cha][b] = 1;
					q.push(node(t.a - cha, b, t.opt + "POUR(1,2)\n", t.step + 1));
				}
			}
		} 
		if (t.b != 0 && t.a != a) {
			int cha = a - t.a;
			if (cha >= t.b) {
				// 将b全部导入a
				if (!vis[t.a + t.b][0]) {
					vis[t.a + t.b][0] = 1;
					q.push(node(t.a + t.b, 0, t.opt + "POUR(2,1)\n", t.step + 1));
				} 
			} else {
				if (!vis[a][t.b - cha]) {
					vis[a][t.b - cha] = 1;
					q.push(node(a, t.b - cha, t.opt + "POUR(2,1)\n", t.step + 1));
				}
			}
		}
	}
	return "impossible";
}
int main() {
	scanf("%d%d%d", &a, &b, &c);
	cout << bfs();
	return 0; 
}