codeup的Jugs题目需要使用扩展欧几里德算法解决:
题目链接:http://codeup.hustoj.com/problem.php?cid=100000609&pid=0
这道题出的有点奇怪,学习下扩展欧几里德算法就行了,不要在这题浪费太多时间
题目的一小段提示:
倒水问题的经典形式是这样的:
“假设有一个池塘,里面有无穷多的水。现有2个空水壶,容积分别为5升和6升。问题是如何只用这2个水壶从池塘里取得3升的水。”
当然题外是有一些合理的限制的,比如从池塘里灌水的时候,不管壶里是不是已经有水了,壶一定要灌满,不能和另一个壶里的水位比照一下“毛估估”(我们可以假设壶是不透明的,而且形状也不同);同样的,如果要把水从壶里倒进池塘里,一定要都倒光;如果要把水从一个壶里倒进另一个壶里,也要都倒光,除非在倒的过程中另一个壶已经满了;倒水的时候水没有损失(蒸发溢出什么的)等等等等。
事实上,要解决上面这题,你只要用两个壶中的其中一个从池塘里灌水,不断地倒到另一个壶里,当第二个壶满了的时候,把其中的水倒回池塘里,反复几次,就得到答案了。以5升壶(A)灌6升壶(B)为例:
A B
0 0
5 0 A→B
0 5
5 5 A→B
4 6
4 0 A→B
0 4
5 4 A→B
3 6
给出100分的AC代码链接:https://blog.csdn.net/xlrll/article/details/105505502
Zoj的jugs题目需要使用BFS算法解决:
题目链接:https://zoj.pintia.cn/problem-sets/91827364500/problems/91827364504
AC代码
#include <stdio.h>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;
struct Jug {
int Ca, Cb;
vector<int> ops;
} tempJug;
int Ca, Cb, N;
string opStr[] = {"fill A", "fill B", "empty A", "empty B", "pour A B", "pour B A"};
bool check(Jug jug, int opNum) {
//其他的校验在switch里面,这里对一些特殊的情况处理
//最后一个操作是fill A,接下来就不要empty A
if(jug.ops[jug.ops.size()-1] == 0 && opNum == 2) {
return false;
}
//最后一个操作是fill B,接下来就不要empty B
if(jug.ops[jug.ops.size()-1] == 1 && opNum == 3) {
return false;
}
//最后一个操作是pour A B,接下来就不要pour B A
if(jug.ops[jug.ops.size()-1] == 4 && opNum == 5) {
return false;
}
//最后一个操作是pour B A,接下来就不要pour A B
if(jug.ops[jug.ops.size()-1] == 5 && opNum == 4) {
return false;
}
return true;
}
void BFS() {
queue<Jug> q;
Jug jug1, jug2;
//放入fill A操作
jug1.Ca = Ca;
jug1.Cb = 0;
jug1.ops.push_back(0);
q.push(jug1);
//放入fill B操作
jug2.Ca = 0;
jug2.Cb = Cb;
jug2.ops.push_back(1);
q.push(jug2);
while(!q.empty()) {
Jug top = q.front();
q.pop();
if(top.Cb == N) {
//打印操作
for(int i = 0; i < top.ops.size(); i++) {
cout<<opStr[top.ops[i]]<<endl;
}
printf("success\n");
return;
}
for(int i = 0; i < 6; i++) {
//防止内存超限或者运行超时!
if(check(top, i) == false) continue;
switch(i) {
case 0:
if(top.Ca < Ca) {
tempJug.Ca = Ca;
tempJug.Cb = top.Cb;
//注意先把top的ops赋值给tempJug的ops
tempJug.ops = top.ops;
tempJug.ops.push_back(0);
q.push(tempJug);
}
break;
case 1:
if(top.Cb < Cb) {
tempJug.Ca = top.Ca;
tempJug.Cb = Cb;
tempJug.ops = top.ops;
tempJug.ops.push_back(1);
q.push(tempJug);
}
break;
case 2:
if(top.Ca > 0) {
tempJug.Ca = 0;
tempJug.Cb = top.Cb;
tempJug.ops = top.ops;
tempJug.ops.push_back(2);
q.push(tempJug);
}
break;
case 3:
if(top.Cb > 0) {
tempJug.Ca = top.Ca;
tempJug.Cb = 0;
tempJug.ops = top.ops;
tempJug.ops.push_back(3);
q.push(tempJug);
}
break;
case 4:
if(top.Cb < Cb && top.Ca > 0) {
int need = Cb - top.Cb;
if(top.Ca >= need) {
tempJug.Cb = Cb;
tempJug.Ca = top.Ca - need;
} else {
tempJug.Cb = top.Cb + top.Ca;
tempJug.Ca = 0;
}
tempJug.ops = top.ops;
tempJug.ops.push_back(4);
q.push(tempJug);
}
break;
case 5:
if(top.Ca < Ca && top.Cb > 0) {
int need = Ca - top.Ca;
if(top.Cb >= need) {
tempJug.Ca = Ca;
tempJug.Cb = top.Cb - need;
} else {
tempJug.Ca = top.Ca + top.Cb;
tempJug.Cb = 0;
}
tempJug.ops = top.ops;
tempJug.ops.push_back(5);
q.push(tempJug);
}
break;
}
}
}
}
int main() {
while(~scanf("%d %d %d", &Ca, &Cb, &N)) {
BFS();
}
return 0;
}