用(0,0)表示桶的初始状态,总共有六种状态的转移方式
当状态变为(x,y),满足x==z或者x==y或者x+y==z时,即找到了问题的解,当所有操作均不能找到问题的解,那么就不行。所以可以用DFS解决,这里要记录下所有的状态,已经有的状态就不再继续搜索。
DFS可以解决,那么用BFS也可以解决。
class Solution {
int capacityX,capacityY;
int[][] state;
boolean flag = false;
public boolean canMeasureWater(int x, int y, int z) {
if(z>x+y) return false;
capacityX = x;
capacityY = y;
state = new int[x+1][y+1];
dfs(0,0,z);
return flag;
}
public void dfs(int x,int y,int z){
if(flag) return;
if(x==z||y==z||x+y==z){
flag = true;
return;
}
if(state[x][y]==1) return;
state[x][y]=1;
dfs(0,y,z); // 将第一个容器的水倒空
dfs(x,0,z); // 将第二个容器的水倒空
dfs(capacityX,y,z); // 将第一个容器的水倒满
dfs(x,capacityY,z); // 将第二个容器的水倒满
dfs(Math.min(x+y,capacityX),Math.max(y-capacityX+x,0),z); // 将第一个容器倒满
dfs(Math.max(x-capacityY+y,0),Math.min(x+y,capacityY),z); // 将第二个容器倒满
}
}
这道题还可以用数学方法来解答,状态的转移等价于一系列的矩阵变换,
注意, C++有标准的gcd函数,不用自己实现。
class Solution {
public:
bool canMeasureWater(int x, int y, int z) {
if(z>x+y) return false;
if(z==0) return true;
return !(z%gcd(x,y));
}
};