现在的位置: 首页 > 综合 > 正文

从倒水问题到欧几里得算法扩展

2017年12月16日 ⁄ 综合 ⁄ 共 944字 ⁄ 字号 评论关闭

  今天在庞果网做了一道题,倒水问题,题目如下,有两个容器,容积分别为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;
    }
  
    
}

抱歉!评论已关闭.