给你两个容量分别为 A 升和 B 升的罐子。可以进行以下操作:
- FILL(i) 从水龙头向罐子 i(1 ≤ i ≤ 2)灌满水;
- DROP(i) 把罐子 i 的水倒空;
- POUR(i,j) 从罐子 i 向罐子 j 倒水;此操作后,要么罐子 j 满了(罐子 i 可能还有水),要么罐子 i 空了(所有水都倒到罐子 j 里)。
编写一个程序,找出能使其中一个罐子中恰好有 C 升水的最短操作序列。
输入
第一行包含三个整数 A、B 和 C。这些数都在 1 到 100 的范围内,且 C ≤ max(A,B)。
输出
输出的第一行必须包含操作序列的长度 K。接下来的 K 行分别描述一个操作。如果有多个最短长度的操作序列,输出其中任意一个。如果无法达到期望结果,输出文件的第一行必须包含单词 ‘impossible’。
示例
Input | Output |
---|---|
3 5 4 | 6 FILL(2) POUR(2,1) DROP(1) POUR(2,1) FILL(2) POUR(2,1) |
解题思路
本题有3总操作,但操作的对象不同,一共有6种不同操作,题目求最短显然用bfs搜索更好一点
我们在找到终点还要回溯其走过的点,这里可以在结构体里面增加一个变量记录是由哪个点来的
最后记得逆序输出答案
#include<stdio.h>
#include<string.h>
struct bbffss {
int x;//横坐标
int y;//纵坐标
int f;//从哪个点来的
int s;
char str[15];
}q[10000005];
int a, b, c, k = 0, top = 0, sum = 0, flag = 0;
int book[101][101], m, n;
char str1[] = "FILL(0)";
char str2[] = "DROP(0)";
char str3[] = "POUR(0,0)";
char sy[100000][15];
void sss(int x, int y,int tail)
{
switch (x)
{
case 1:
strcpy(q[tail].str, str1);
q[tail].str[5] += y;
break;
case 2:
strcpy(q[tail].str, str2);
q[tail].str[5] += y;
break;
case 3:
strcpy(q[tail].str, str3);
if (y == 1)
{
q[tail].str[5] += 1;
q[tail].str[7] += 2;
}
else
{
q[tail].str[5] += 2;
q[tail].str[7] += 1;
}
break;
}
}
void bfs()
{
int hard = 1, tail = 2, tx, ty;
book[0][0] = 1;
q[1].x = 0; q[1].y = 0;
q[1].f = 0; q[1].s = 0;
while (hard < tail)
{
for (int j = 1; j <= 2; j++)//两种不同的操作对象
{
for (int i = 1; i <= 3; i++)//三种操作方式
{
//根据操作方式和对象的不同
switch (i)
{
case 1:
if (j == 1)
{
tx = a;
ty = q[hard].y;
}
else
{
tx = q[hard].x;
ty = b;
}
break;
case 2:
if (j == 1)
{
tx = 0;
ty = q[hard].y;
}
else
{
tx = q[hard].x;
ty = 0;
}
break;
case 3:
m = q[hard].x;
n = q[hard].y;
if (j == 1)
{
if (b - n >= m)
{
tx = 0;
ty = n + m;
}
else
{
tx = m - (b - n);
ty = b;
}
}
else
{
if (a - m >= n)
{
tx = n + m;
ty = 0;
}
else
{
tx = a;
ty = n - (a - m);
}
}
break;
}
if (book[tx][ty] == 1)
continue;
book[tx][ty] = 1;//标记存在这种情况
//入队操作
q[tail].x = tx; q[tail].y = ty;
q[tail].f = hard; q[tail].s = q[hard].s + 1;
sss(i, j, tail);
if (tx == c || ty == c)//判断是否到达指定容量
{
int ff = tail;
sum = q[tail].s;
while (ff != 0)
{
strcpy(sy[++top], q[ff].str);
ff = q[ff].f;
}
flag = 1;
return;
}
tail++;
}
}
hard++;
}
}
int main()
{
scanf("%d %d %d", &a, &b, &c);//输入a,b,c
bfs();//进行搜索
if (flag == 1)//有答案进行输出
{
printf("%d\n", sum);
for (int i = top - 1; i >= 1; i--)//逆序输出
printf("%s\n", sy[i]);
}
else//没有答案
printf("impossible\n");
return 0;
}