蓝桥杯-最大最小公倍数java语言

8 篇文章 0 订阅

蓝桥杯-最大最小公倍数java语言

开局一句话:

做这道题的时候,便没有对最小公倍数十分了解,就直接写了,也是惭愧,走了太多弯路,后来才知道,最小公倍数不是单单的几个数相乘就完了。

问题描述:

已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。

输入格式:

输入一个正整数N。

样例输入:

9

样例输出:

504

数据规模与约定

1 <= N <= 106

以下思路是来自于博主
阿拉伯字母二世
的博客

开始:

题目分析:

这应该算是考究数学知识的一道题
 先提出一个问题:假设有三个正整数a、b、c,我们如何求得它们的最小公倍数?
 这个问题的有个简单直接的解决方法:
 1.调整a、b、c的值,使得a的值最大。
 2.将a和另一个正整数n相乘,判断相乘结果是否同时为b、c的倍数,如果是,则结束循环,否则,n自增后继续和a做乘法,直到相乘结果同时为b、c的倍数。
 上述方法其实就是通过穷举的方式寻找出三个最小公倍数,可以,但是没必要,因为在数据量大的时候性能会很差。
 有一个数学常识大家都知道:三个正整数的最小公倍数不会大于这三个数的乘积
 也就是说,a、b、c三个数的最小公倍数最大的时候就是 a * b * c
 那么问题来了,当a、b、c满足什么条件时,它们的最小公倍数是他们的乘积呢?
 我们可以先简化这个问题——当两个正整数的值满足什么条件时,它们的最小公倍数最大?
 显然,当这两个数互质时,它们的最小公倍数最大,也就是它们的乘积
 那么在正整数个数增加到三个的时候,当他们的数值关系为两两互质的时候,它们的最小公倍数为它们的乘积。
 题目要求我们在1 ~ N之间任意选择三个数,使得它们的最小公倍数最大。
 要使得最小公倍数最大,那么思路可以是:
1.这三个数要两两互质
2.在满足1的前提下,使得三个整数取最大值

第一点已经在上面分析过了。而第2点也很好理解,其实就是贪心策略。

算法分析:

根据N的取值的不同主要有三种情况:

1. N为奇数时

当N为奇数时,N - 1为偶数,N - 2为奇数,显然,数学知识告诉我们,相邻的两个正整数互质。同样的,相邻的两个奇数也是互质的,那么此时题目要求的答案为N * (N - 1) * (N - 2)。

2. N为偶数时

因为当N >3时,N 和当N - 3是可能不是互质的,例如3和6。所以偶数时又分为两种可能性:

2.1 当3不能整除N时

当N为偶数时,N - 2同样为偶数,那么就不能满足上面思路的第1点了。但是N和N - 1还是互质的,所以在贪心策略下,我们优先考虑使用更小的值去替换N - 2,而不是替换N 和 N - 1。经计算发现 N - 3满足要求,所以此时答案为N * (N - 1) * (N - 3)。

2.2 当3能整除N时

因为N能够被3整除,所以N - 3同样能被3整除,为了不违反第1点,我们再次优先用更小的值替代 N - 3(为什么又是换掉第三个?因为我贪心啊)。我们先尝试使用N - 4。但是因为N是偶数,那么N - 4也是偶数,显然这也是不满足第1点的。我们再尝试使用N - 5。也就是N * (N - 1) * (N - 5) = n3 - 6 * n2 + 5 * n。这个也是不可以的,因为当N = 10时,N - 5 = 5,同样不满足第1点。
 ……好像有点没完没了
所以根据贪心策略,在放弃修改最小的数(在这里是N - 3)时,我们优先考虑换掉第中间大小的数(在这里是N - 2)。但是会发现,无论是使用N - 3、N - 4、N - 5……中的哪一个去替换N - 2,其结果都是跟替换最小的数(在这里是N - 3)的结果是一样的。所以我们只能开始考虑使用更小的值去替换最大的数,也就是N。因为采用的是贪心策略,所以我们优先考虑使用N - 1去替换N,此时结果是:(N - 1) * (N - 2) * ( N - 3)。
显然相邻的两个正整数是互质的,我们只要考虑N - 1和N - 3是否互质就可以了。
因为N - 1和 N - 3实际上等同于第1种情况,即N为奇数时,故 (N - 1) * (N - 2) * ( N - 3) 就是题目答案了。这就是那位博主的想法,不得不说很细,他的是C语言代码,我的是Java语言的,换汤不换药。

java代码:

import  java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long n = sc.nextInt();
        if(n%2!=0){
            System.out.println(n*(n-1)*(n-2));
        }
        if(n%2==0){
            if(n%3!=0)
            {
                System.out.println(n*(n-1)*(n-3));
            }
            else{
                System.out.println((n-1)*(n-2)*(n-3));
            }
        }

    }
}

总结:

所以还是要细心,需要一颗善于发现的心。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值