算法训练 ALGO-2 最大最小公倍数(贪心算法)

算法训练 最大最小公倍数  
时间限制:1.0s   内存限制:256.0MB
       
问题描述

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

输入格式

输入一个正整数N。

输出格式
输出一个整数,表示你找到的最小公倍数。
样例输入
9
样例输出
504
数据规模与约定

1 <= N <= 106


第一次做的代码如下:(0分)

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		int N = scanner.nextInt();
		int[] a = new int[N];
		for(int i=0;i<N;i++){
			a[i]=i+1;
		}
		int sum=0;
		for(int i=1;i<=N;i++){
			for(int j=1;j<=N;j++){
				for(int k=1;k<=N;k++){
					int temp=i*j*k;
					if(i!=j&&i!=k&&j!=k&&temp>sum){
						sum=temp;
					}
				}
			}
		}
		System.out.println(sum);
	}

}


在把第一次代码提交上去的时候,发现已经运行超时了,而且没有考虑当n为奇数、偶数、3的倍数的前提下。


然后在网上看到有大神用简单贪心算法进行解答这一题目。

简答的了解一下贪心算法:

**解题的一般步骤是:
1.建立数学模型来描述问题;
2.把求解的问题分成若干个子问题;
3.对每一子问题求解,得到子问题的局部最优解;
4.把子问题的局部最优解合成原来问题的一个解。(https://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741375.html)


以下内容转载一下地址博客:http://blog.csdn.net/violet_echo_0908/article/details/50602042 和 http://blog.csdn.net/yf224/article/details/72649765

定理1:大于1的两个相邻的自然数必定互质 。
定理2:两个数的最小公倍数在最大的情况就是当两个数互质的时候,他们的最小公倍数就是这两个数的乘积。


在百度百科找到的理解有多个数的最小公倍数:


1、 n为奇数 (奇数-偶数-奇数)
      此时,n*(n-1)*(n-2)中,n,n-1为偶数,n-2为奇数即肯定不存在公因数2,因为这三个连续的数变化范围不超过3,所以就算有一个数是3的倍数,也不会存在第二个数是3的倍数,即这三个数字都是互质的。(例子:15,14,13和9,8,7)


2、 n为奇数 (偶数-奇数-偶数)

      两个偶数肯定有公约数,即存在公因数2,也就是说最小公倍数要除2了,就不是最大了的。

    所以不能存偶 X 奇 X 偶 这种情况,就让(n-2)变为(n-3),大的数尽量不变嘛,这时候呢,又恢复到了奇*偶*奇的情况,所以选择n 、n-1、n-3这三个当前最大的数n-3与n相差三,若n是3的倍数 则n与n-3有公约数,此时选择 n-1、n-2、n-3 这三个当前最大的数 此时状态为“偶-奇-偶” 肯定互质,此时最大最小公倍数为(n-3)*(n-1)*(n-2)。 若n不是3的倍数则 最大最小公倍数为n*(n-1)*(n-3)。


3、其实看题时看漏了一个关键的地方,数据规模是10的6次方,所以数据类型应选择long类型。

顺便补一下类型的范围知识:

byte类型是1个字节,一个字节8位,1*8=8,2的7次方(2^7)是128(3位数字)。

short类型是2个字节,一个字节8位,2*8=16,2的15次方(2^15)是32768(5位数字)。

int类型是4个字节,一个字节8位,4*8=32,2的31次方(2^32)是2147483648(10位数字)。

long类型是8个字节,一个字节8位,8*8=64,2的63次方是(2^63)是9223372036854775808(19位数字)

第二次代码如下:(100分)

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scanner = new Scanner(System.in);
		long n = scanner.nextLong();
		long b = 0;
		if(n%2==1){//奇数*偶数*奇数
			b=n*(n-1)*(n-2);
		}else if(n%3!=0){//偶数*奇数*偶数
			b=n*(n-1)*(n-3);
		}else{//奇数*偶数*奇数
			b=(n-3)*(n-1)*(n-2);
		}
		System.out.println(b);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值