蓝桥杯--数学知识的运用(二)

例6【因数分解】

求两个数的最大公约数与最小公倍数

解析:关键在算数基本定理--质因数分解的唯一性
      欧几里得定理:gcd(a,b) = gcd(b,a%b) ---一个数能除开 A,B, 那么一定能除开A-B  A+B
      最小公倍数 = 乘积 / 最大公约数
public class Main {
    //greatest common divisor
    static int gcd(int a,int b){
        if(b==0)
            return a;
        return gcd(b,a%b);
    }
    //lowest common muultiple
    static  int lcm(int a,int b){
        return a * b / gcd(a,b);
    }

    public static void main(String[] args) {
        System.out.println(gcd(60,42));// 6
        System.out.println(lcm(60,42));// 420
    }
}

例7【一步之遥】

从昏迷中醒来,小明发现自己被关在X星球的废矿车里。
矿车停在平直的废弃的轨道上。
他的面前是两个按钮,分别写着“F”和“B”。

小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。
按F,会前进97米。按B会后退127米。
透过昏暗的灯光,小明看到自己前方1米远正好有个监控探头。
他必须设法使得矿车正好停在摄像头的下方,才有机会争取同伴的援助。
或许,通过多次操作F和B可以办到。

矿车上的动力已经不太足,黄色的警示灯在默默闪烁...
每次进行 F 或 B 操作都会消耗一定的能量。
小明飞快地计算,至少要多少次操作,才能把矿车准确地停在前方1米远的地方。

请填写为了达成目标,最少需要操作的次数。

解析:97x + 127y = 1....不定方程的整数解

扩展欧几里得定理:
   Ax + By = gcd(A,B) 必有解,求解方法: 

A分解成 A/B*B+A%B  =》 凑A%B

public class Main {
    //解不定方程 97x+127y=1
    static int e_gcd(int x,int y,int []xy) {
        if(y==0){
            xy[0] = 1;
            xy[1] = 0;
            return x;
        }
        int gcd = e_gcd(y,x%y,xy);
        int t = xy[0];
        xy[0] = xy[1];
        xy[1] = t - x/y * xy[0];
        return gcd;
    }
    public static void main(String[] args) {
       int []xy = new int[2];
        System.out.println(e_gcd(97,127,xy));
        System.out.println("x:" + xy[0] + "  y:" + xy[1]);//x:55  y:-42
    }
}

例8【素数表】

第1个素数是2,第2个素数是3,...求第100002(十万零二)个素数

解析:利用素数的筛法,而关键在于数组应该开多大--素数分布密度公式 

           素数分布定理:不大于n的素数个数为:n / ln(n)

  public static void main(String[] args) {
       /* double t = 100;
        while(t / Math.log(t) < 100002)
            t = t * 1.1;
        System.out.println(t);//N = 1515867.357380462*/
        int N = 1520 * 1000;
        int x = 100002;
        byte[]a = new byte[N];//使用byte数组节省空间
        for(int i=2;i<N/2;i++){
            if(a[i] == 1)//越过已经找到的合数
                continue;
            for(int k=2;k<=N/i;k++)
                if(i*k<N) a[i*k] = 1;
        }
        int sum = 0;
        for(int i=2;i<N;i++){
            if(a[i]==0)
                sum++;
            if(sum==x){
                System.out.println(i);//1299743
                break;
            }
        }

    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值