这个问题有一个更简单的解决方案。不需要 BFS。Ad-hoc 会做得很好。方法1-填充A,将其清空到B中。每当A变空时,将其重新填充,每当B变满时,将其清空。(所有上述动作都算作单独的动作)。继续此过程,直到您在任何一个容器中达到所需的水量。在此处获取移动次数。(说C1
)。
方法2-填充B,将其清空到A中。每当B变空时,将其重新填充,每当A变满时,将其清空。继续此操作,直到您达到所需的金额。获取移动数说C2
)。
答案是min(C1,C2)
。
C++源代码:
#include < cstdio >
#include < algorithm >
using namespace std;
int pour(int A, int B, int C) {
int move = 1, a = A, b = 0, tfr;
while (a != C && b != C) {
tfr = min(a, B - b);
b += tfr;
a -= tfr;
move++;
if (a == C || b == C)
break;
if (a == 0) {
a = A;
move++;
}
if (b == B) {
b = 0;
move++;
}
}
return move;
}
/** Reason for calculating GCD of a,b is to check whether an integral solution of
* equation of form ax + by = c exist or not, to dig deeper read Diophantine Equations
*/
int gcd(int a, int b) {
if (b == 0)
return a;
return gcd(b, a % b);
}
int main() {
int t, a, b, c;
scanf("%d", & t);
while (t--) {
scanf("%d%d%d", & a, & b, & c);
if (c > a && c > b)
printf("-1\n");
else if (c % gcd(a, b) != 0)
printf("-1\n");
else if (c == a || c == b)
printf("1\n");
else
printf("%d\n", min(pour(a, b, c), pour(b, a, c)));
}
return 0;
}