“1-n的最小公倍数问题”蓝桥杯

本文详细介绍了如何通过有效因子的概念来快速计算1至n的最小公倍数,并提供了C语言和Java两种实现方式。通过分析因子的最高次幂和剔除操作,简化了大数处理过程,提高了计算效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.  公倍数

 

为什么1小时有60分钟,而不是100分钟呢?这是历史上的习惯导致。

但也并非纯粹的偶然:60是个优秀的数字,它的因子比较多。

事实上,它是1至6的每个数字的倍数。即1,2,3,4,5,6都是可以除尽60。

 

我们希望寻找到能除尽1至n的的每个数字的最小整数。

 

不要小看这个数字,它可能十分大,比如n=100, 则该数为:

69720375229712477164533808935312303556800

 

请编写程序,实现对用户输入的n (n<100)求出1~n的最小公倍数。

 

例如:

用户输入:

6

程序输出:

60

 

用户输入:

10

程序输出:

2520

 

要求考生把所有函数写在一个文件中。调试好后,存入与考生文件夹下对应题号的“解答.txt”中即可。

相关的工程文件不要拷入。

对于编程题目,要求选手给出的解答完全符合ANSI C标准,不能使用c++特性;

不能使用诸如绘图、中断调用等硬件相关或操作系统相关的API。


原题是C的题目,找了些资料是实现如下(同时我也用java实现了,原理有细微差别):

#include<stdio.h>
/************************************************************************/
/* 原理:
找出n个数中所有有效因子相乘得到结果(含大数处理)
有效因子:1.当某因子A出现,取其最高次幂(但结果不大于n)为有效因子A^x
		  2.把该因子A的所用倍数从这n个数中剔除(即不做任何处理)
                                                                     */
/************************************************************************/
void main(){
	int sum[200]={1},sn=1,n;
	int perm[50]={0},pn=0;	
	int i,j,k,h;

	scanf("%d",&n);

	for(k=2;k<=n;k++){
		for(i=0;i<pn;i++){
			if(k%perm[i]==0)//只出现过的因子,其倍数均不重复计入
				break;
		}
		if(i==pn){
			perm[pn]=k;
			pn++;
			j=k*k;
			while(j<=n)//当某因子出现,取其最高次幂(结果不大于n)
				j=j*k;

			h=0;
			j = j/k ;
			for(i=0 ; i < sn ; i++){//大数处理
				sum[i] = sum[i] * j + h;
				h = sum[i]/10000 ;
				sum[i] = sum[i]%10000 ; 				
			}
			if(h){
				sum[sn] = h ;
				sn++;
			}
		}
	}
	for(i=sn-1;i>=0 ;i--){
		printf("%d",sum[i]);	
	}
	printf("\n");
}



以下是java实现(递归),条理会更清楚些:

package c_coding;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class CommonMultiple {
	int N = 100;
	static List<Integer> list = new ArrayList<Integer>();
	public void getFactor(List<Integer> list,int index){
		if(index>N) {
			calculate();
			return;
		}
		int temp = index;
		for(int i=1;i<list.size();i++) {
			int factor = list.get(i);
			if(temp%factor==0) 
				temp = temp/factor;
		}
		list.add(temp);
		getFactor(list,index+1);
	}
	
	public void calculate(){
		BigInteger num = BigInteger.valueOf(1);
		for(int i=0;i<list.size();i++) {
			num = num.multiply(BigInteger.valueOf(list.get(i)));
		}
		list.clear();
		System.out.println(num);
	}
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		CommonMultiple test = new CommonMultiple();
		while(true){
			System.out.println("用戶輸入:");
			test.N = scanner.nextInt();
			System.out.println("程序輸出:");
			test.getFactor(list, 1);
		}
		
	}

}


 

### 蓝桥杯 2002 年最小公倍数题目解析 #### 题目描述 给定一个正整数 \( N \),要求找出三个不大于 \( N \) 的不同正整数,使得这三个数的最小公倍数最大。 #### 解题思路 为了使三个数的最小公倍数最大化,在选择这些数时需遵循特定策略: - 当 \( N \) 是奇数时,可以选择 \( N, N-1, N-2 \)[^3]。由于相邻的奇数之间的最大公约数为 1,因此三者的乘积即为其最小公倍数。 ```cpp if (N % 2 != 0) { result = N * (N - 1) * (N - 2); } ``` - 如果 \( N \) 是偶数,则需要进一步区分两种情形: - 若 \( N \) 不是 3 的倍数,同样可选 \( N, N-1, N-3 \)[^5]; ```cpp else if (N % 3 != 0) { result = N * (N - 1) * (N - 3); } ``` - 反之,若 \( N \) 同时也是 3 的倍数,则应排除 \( N \),改用 \( N-1, N-2, N-3 \) 来确保得到更大的最小公倍数值。 ```cpp else { // 即 N % 3 == 0 && N % 2 == 0 result = (N - 1) * (N - 2) * (N - 3); } ``` 通过上述逻辑判断并计算相应的表达式,便能获得满足条件的最大最小公倍数。 #### 实现代码示例 以下是基于以上分析编写的 C++ 程序片段来解决此问题: ```cpp #include <iostream> using namespace std; int main() { long long N; cin >> N; // 输入范围内的任意正整数 long long result; if (N % 2 != 0 || N % 3 != 0) { result = N * (N - 1) * ((N % 2 == 0) ? (N - 3) : (N - 2)); } else { result = (N - 1) * (N - 2) * (N - 3); } cout << result << endl; // 输出结果 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值