zoukankan      html  css  js  c++  java
  • 从倒水问题到欧几里得算法扩展

      今天在庞果网做了一道题,倒水问题,题目如下,有两个容器,容积分别为A升和B升,有无限多的水,现在需要C升水。 我们还有一个足够大的水缸,足够容纳C升水。起初它是空的,我们只能往水缸里倒入水,而不能倒出。 可以进行的操作是: 把一个容器灌满; 把一个容器清空(容器里剩余的水全部倒掉,或者倒入水缸); 用一个容器的水倒入另外一个容器,直到倒出水的容器空或者倒入水的容器满。问是否能够通过有限次操作,使得水缸最后恰好有C升水。  

      本小菜鸟对算法题根本就没什么研究,好在有万能的百度,简单看了看,说是欧几里得的算法扩展,百度了下欧几里得算法,其实不过就是辗转相除求最大公约数,高中就有学过这个但是,并不知道叫欧几里得算法。

      闲话不多说,还是回到题目,已知容积A升和B升,那么我们能倒出的水的量为,A、B、A-B、A+B四种,也就是说只要判断是否存在这样的x1、x2、x3、x4 令

     x1*A+x2*B+x3*(A-B)+x4*(A+B)=C

      当然我们可以用循环来进行操作,但是这样显然是费力不讨好的,我们把公式整理一下

    (x1+x3+x4)*A+(x2-x3+x4)*B=C

    现在就变成了

    X*A+Y*B=C

    根据欧几里得算法的扩展定理

    定理
    对于不完全为 的非负整数 abgcdab)表示 a的最大公约数,必然存在整
    数对 x,使得 gcdab=ax+by

    那么只要Cgcdab)的倍数就返回true,反之返回false

    java实现如下

     

    import java.io.*;
    import java.math.BigInteger;
    import java.util.*;
    
    public class Main {
        public static boolean can(int a,int b,int c) {
        	int res;  
            res=mod(a,b);  
              
            if(c%res==0)  
                return true;    
            else   
                return false;  
        }
    
        
        
         public static void main(String args[]) 
        { 
        	System.out.print(can(0,1,1000000000)); 
    
        } 
        public static int mod(int a,int b){
            if(b>=1){
            	return mod(b, a%b);
            }
            else return a;
        }
      
        
    }


  • 相关阅读:
    每天写点shell——read的用法
    串口编程(一) :理论基础
    常用算法3
    Linux man C++ 库函数
    网络爬虫(一):配置selenium、pycharm(windows平台)
    C/C++ 类型内存占用详解
    git常用命令总结
    常用算法2
    本地git关联远程github
    python实现float/double的0x转化
  • 原文地址:https://www.cnblogs.com/riskyer/p/3327494.html
Copyright © 2011-2022 走看看