1、题目描述
有两个容量分别为 x升 和 y升 的水壶以及无限多的水。请判断能否通过使用这两个水壶,从而可以得到恰好 z升 的水?
如果可以,最后请用以上水壶中的一或两个来盛放取得的 z升 水。
你允许:
装满任意一个水壶
清空任意一个水壶
从一个水壶向另外一个水壶倒水,直到装满或者倒空
2、示例
输入: x = 3, y = 5, z = 4
输出: True
3、题解
解法一:
基本思想:递归dfs深度优先搜索,超时,将x与y相减得到的数cur保存至res,然后cur与res中所有数相减得到新的数加入res,这个过程中如果cur=z,则返回true
解法二:
基本思想:数学,贝祖定理,找到x,y的最大公约数能否z被整除
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
using namespace std;
class Solution {
public:
set<int> res;
bool canMeasureWater(int x, int y, int z) {
//基本思想:递归dfs深度优先搜索,超时
//将x与y相减得到的数cur保存至res,然后cur与res中所有数相减得到新的数加入res
//这个过程中如果cur=z,则返回true
if(z==x||z==y||x+y==z||z==0) return true;
res.insert(x);
res.insert(y);
int cur=x>y?x-y:y-x;
return dfs(cur,z);
}
bool dfs(int cur,int z)
{
if(res.find(cur)!=res.end())
return false;
if(cur==z)
return true;
for(auto iter=res.begin();iter!=res.end();iter++)
{
if(cur+*iter==z)
return true;
}
res.insert(cur);
for(auto iter=res.begin();iter!=res.end();iter++)
{
if(*iter==cur)
continue;
else if(*iter>cur&&dfs(*iter-cur,z))
return true;
else if(cur>*iter&&dfs(cur-*iter,z))
return true;
}
return false;
}
};
class Solution1 {
public:
bool canMeasureWater(int x, int y, int z) {
//基本思想:数学,找到x,y的最大公约数能否z被整除
if (x + y < z)
return false;
if (z == 0 || x + y == z)
return true;
if(x>y) swap(x,y);
if(x==0) return y==z;
while(y%x!=0)
{
int temp=x;
x=y%x;
y=temp;
}
return z % x == 0;
}
};
int main()
{
Solution1 solute;
int x=2,y=6,z=5;
cout<<solute.canMeasureWater(x,y,z)<<endl;
return 0;
}