唯一分解定理

唯一分解定理

定理:任何一个大于等于2的正整数都可以写成若干个素数幂相乘的形式。
举个例子:60=2 * 2 * 3 * 5
代码实现:

int main(){
	int m=sqrt(n);
	for(int i=2;i<=m;i++){//从2开始,到n的开平方结束
		if(n%i==0){//判断i是否是n的因数
			base[cnt++]=i;
			while(n%i==0){
				n/=i;
				power[cnt]++;
			}
		}
	}
	if(n>1){//特殊情况
		base[++cnt]=n,power[cnt]=1;
	}
}

下面来看几道题:

乘积为n的素数

题目描述

给你一个正整数n(n>=2&&n<=1000000)根据唯一分解定理输出素数x1、x2、x3…xk,x1<=x2<=x3<=…<=xk,并且x1x2x3*…*xk等于n。

输入描述

输入一个正整数n。

输出描述

第一行输出k,
第二行输出素数x1,x2…xk使它们的乘积为n。

样例

输入
10
输出
2
2 5

代码

#include<iostream>
#include<cmath>
using namespace std;
int a[500000];//定义
int main(){
    int n,cnt=0;
    cin>>n;//输入
	int m=sqrt(n);//唯一分解定理代码
	for(int i=2;i<=m;i++){
		if(n%i==0){
			while(n%i==0){
			    cnt++;
			    a[cnt]=i;
				n/=i;
			}
		}
	}
	if(n>1){
		a[++cnt]=n;
	}
	cout<<cnt<<endl;//输出
	for(int i=1;i<=cnt;i++){
	    cout<<a[i]<<" ";
	}
	return 0;
}

LCM为n的最小因子和

题目描述

LCM可以看成一组数的最小公倍数,即这些数公有的倍数。比如1 12的最小公倍数是12,3、4、5的最小公倍数为60。现如今给你一个正整数n,你必须发现一组数(这个组的大小必须大于1),使这一组数的LCM为n,同时使这一组数的和最小,并输出最小的和。比如如果给定n为12,1、12和3、4的LCM都为n,但是12+1>3+4所以最后的结果输出7。

输入描述

输入一个正整数n(2<=n<=10^9)

输出描述

按要求输出最小的和。

样例

输入
12
输出
7

做题思路

假设 n=60,则因子可能是:
3 20
2 3 10
6 10
当a,b>1时,a+b<=a*b
3+20<=60
2+10<=20
2+5<=10
但是2, 3,5的LCM并不是60
而4, 3,5的LCM为60
按照唯一分解定理分解60:
60 = 22 ∗ 31 ∗ 51
所以我们实际上要按照唯一分解定理分解n,然后将每个分解出来的每个质数的幂进行加和就能得到最终结果。

代码

#include<iostream>
#include<cmath>
using namespace std;
long long a[500000];
int main(){
    long long n,cnt=0,sum=0,x;
    cin>>n;
	for(long long i=2;i<=n;i++){
		if(n%i==0){
		    cnt++;
		    x=0;
			while(n%i==0){
			    x++;
				n/=i;
			}
			a[cnt]=pow(i,x);
		}
	}
	if(cnt==1){
	    cnt++;
	    a[cnt]=1;
	}
	for(long long i=1;i<=cnt;i++){
	    sum+=a[i];
	}
	cout<<sum;
	return 0;
}

输出因子

题目描述

给一个正整数n,(n>=2&&n<=1000000000),从小到大输出n的所有因子,包括1和它本身,比如如果输入n为16,则它的所有的因子为1 2 4 8 16

输入描述

一个正整数n

输出描述

从小到大输出n的所有的因子。

样例

输入
10
输出
1 2 5 10

代码

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
long long n,s[100000],cnt;//定义
int main(){
    cin>>n;//输入
	int l=sqrt(n);
	for(int i=1;i<=l;i++){//从一遍历到n的开平方
		if(n%i==0){//判断i是n的因数
		    int x=n/i;
			if(x==i){//判断两个因数是否相同
			    s[++cnt]=i;
			}
			else{
				s[++cnt]=x;
				s[++cnt]=i;
			}
		}
	}
	sort(s+1,s+cnt+1);//排序
	for(int i=1;i<=cnt;i++){
	    cout<<s[i]<<" ";//输出
	}
	return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值