算法实战6:倒水问题

题目详情

有两个容器,容积分别为A升和B升,有无限多的水,现在需要C升水。

我们还有一个足够大的水缸,足够容纳C升水。起初它是空的,我们只能往水缸里倒入水,而不能倒出。

可以进行的操作是:

  1. 把一个容器灌满;
  2. 把一个容器清空(容器里剩余的水全部倒掉,或者倒入水缸);
  3. 用一个容器的水倒入另外一个容器,直到倒出水的容器空或者倒入水的容器满。
    问是否能够通过有限次操作,使得水缸最后恰好有C升水。


输入:三个整数A, B, C,其中 0 < A , B, C <= 1000000000

输出:0或1,表示能否达到要求。


-----------------------------------------------
确实很简单,不过第一遍还是写错了。。。

可能题目有点绕,就是想要实现A被子和B被子之间互倒的解决办法来盛满C容器的被子,但是这里倒水必须是在一方空或者一方满才停止的。
我们模拟下假设A>B  那么可以出现的加数因子是A  B  A-B  但这只是一次的倒水,如果A-B继续和B在倒,我们发现,这里就是一个求余的过程。
在深入下去,就是一个辗转相除求余数,找出A B被子的最大公因数,看看C能否被这个公因数给整除咯,可以的话那就return true
下面给一个c=xa+ yb的公式代码,这种比较好理解,后面给出仅依靠公因数来求得函数
#include <cstdio>
#include <cstring>
#include <string>

using namespace std;



bool can(int a,int b,int c) {
    if(a<b){
        int temp = a;
        a = b;
        b = temp;
    }

    while(1){
        int yu = a%b;
        if(yu == 0){
            if(c%b == 0)
                return true;
            else
                return false;
        }
        if(yu == 1){
            a = b;
            b = 1;
            return true;
        }
        a = yu;
        if(yu<b){
            a = b;
            b = yu;
        }
    }
    int n = c/a;
    int i = 0;
    for(i=0;i<=n;i++){
        if((c-i*a)%b == 0)
            return true;
    }
    return false;
}


int main()
{   
    if(can(16,5,254))
        printf("can");
} 


利用辗转相除法
#include <cstdio>
#include <cstring>
#include <string>

using namespace std;


int mod(int a, int b){
    int yu = a%b;
    if(yu == 0)
        return b; //be careful Here!!!
    if(yu<b)
        return mod(b,yu);
    else
        return mod(yu,b);
}

bool can(int a,int b,int c) {
    int yue = a>b?mod(a,b):mod(b,a);
    if(c%yue == 0)
        return true;
    else
        return false;
}


int main()
{   
    if(can(16,5,254))
        printf("can");
} 



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值