Contest100000592 - 《算法笔记》5.5小节——数学问题->质因子分解

Contest100000592 - 《算法笔记》5.5小节——数学问题->质因子分解

5.5小节——数学问题->质因子分解

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

质因子分解代码

//质因子分解
struct factor
{
	int x,,cnt;//x为质因子,cnt为其个数	
}fac[10];

//枚举1~sqrt(n)范围内的所有质因子p,判断p是否为n的因子 
if(n % prime[i] == 0)//若果prime[i]是n的因子
{
	fac[num].x = prime[i];//记录该因子
	fac[num].cnt = 0;
	while(n % prime[i] == 0)//计算出质因子prime[i]的个数
	{
		fac[num].cnt++;
		n /= prime[i];	
	}	
	num++;//不同质因子个数加一 
} 

if(n != 1)//如果无法被根号n以内的质因子除尽
{
	fac[num].x = n;//那么一定有一个大于根号n的质因子
	fac[num++].cnt = 1;	
}

例题PAT-A-1059-Prime-Factors

题目链接:
https://pintia.cn/problem-sets/994805342720868352/problems/994805415005503488
在这里插入图片描述

//例题PAT-A-1059-Prime-Factors
#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;

const int maxn = 100010;
bool is_prime(int n)//判断n是否为素数
{
	if(n==1)	return false;
	int sqr = (int)sqrt(1.0*n);
	for(int i=2;i<=sqr;i++)
	{
		if(n%i==0)
			return false;	
	}	
	return true;
} 

int prime[maxn],pNum = 0;

void Find_Prime()//求素数表
{
	for(int i=1;i<maxn;i++)
	{
		if(is_prime(i) == true)
			prime[pNum++] = i;
	}	
} 

struct factor
{
	int x,cnt;//x为质因数,cnt为其个数 
}fac[10];


int main()
{
	Find_Prime();
	int n,num=0;//num为n的不同的质因子个数
	scanf("%d",&n);
//	cin>>n;
	if(n == 1)	
		printf("1=1");	
	//	cout<<"1=1";
	else
	{
		printf("%d=",n);
	//	cout<<n<<"=";
		int  sqr = (int)sqrt(1.0*n);//n的根号
		//枚举根号n以内的质因子
		for(int i=0;i<pNum && prime[i] <= sqr;i++)
		{
			if(n % prime[i] == 0)//如果prime[i]是n的质因子
			{
				fac[num].x = prime[i];//记录该因子
				fac[num].cnt = 0;
				while(n % prime[i] == 0)//计算出质因子的个数
				{
					fac[num].cnt++;
					n /= prime[i];	
				} 
				num++;//不同质因子个数加一 
			}	
			if(n == 1)	break;//及时退出循环节省时间 
		}	
		if(n != 1)//如果无法被根号n以内的质因子除尽
		{
			fac[num].x = n;//那么一定有 一个 大于根号n的质因子
			fac[num++].cnt = 1;	
		}
		//按格式输出结果
		for(int i=0;i<num;i++)
		{
			if(i>0)	cout<<"*";
			cout<<fac[i].x;
			if(fac[i].cnt > 1)
			{
				cout<<"^"<<fac[i].cnt;	
			}	
		} 
	} 
	return 0;
}
 

在这里插入图片描述

Codeup习题

Codeup习题-Contest100000592 - 《算法笔记》5.5小节——数学问题->质因子分解
题目链接:http://codeup.cn/contest.php?cid=100000592

1783-Problem-A-完数

题目链接:http://codeup.cn/problem.php?cid=100000592&pid=0

//1783-Problem-A-完数
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

bool isFull(int num)
{
	int sum = 0;
//	int sqr = (int)sqrt(1.0*n);
//	for(int i=2;i<=sqr;i++)
//此处不能用sqrt(),原因不明 
	for(int i=1;i<num;i++)
	{
		if(num % i == 0)
		{
			sum+=i;	
		}
	}
	return sum==num;
}

int main()
{
	int n;
	while(cin>>n)
	{
		bool flag = false;
		for(int i=2;i<=n;i++)
		{
			if(isFull(i))
			{
				if(flag)
					cout<<" ";
				cout<<i;
				flag = true;
			}
		}
		cout<<endl;
	}
	return 0;
}



1783-Problem-B-完数(同上题)

题目链接: http://codeup.cn/problem.php?cid=100000592&pid=1



1947-Problem-C-质因数的个数

题目链接:http://codeup.cn/problem.php?cid=100000592&pid=2

//1947-Problem-C-质因数的个数
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int maxn = 100010;

/*书上的方法不知道咋运行错误,在DEVC++上还好好的 
bool is_prime(int n)//判断n是否为素数
{
	if(n==1)	return false;
	int sqr = (int)sqrt(1.0*n);
	for(int i=2;i<=sqr;i++)
	{
		if(n%i==0)
			return false;	
	}	
	return true;
} 

int prime[maxn],pNum = 0;

void Find_Prime()//求素数表
{
	for(int i=1;i<maxn;i++)
	{
		if(is_prime(i) == true)
			prime[pNum++] = i;
	}	
} 

struct factor
{
	int x,cnt;//x为质因数,cnt为其个数 
}fac[10];


int main()
{
	Find_Prime();
	int n,num=0;//num为n的不同的质因子个数
	while(cin>>n)
	{
		memset(fac,0,sizeof(fac)*100);
		int result = 0;
		if(n == 1)		
			cout<<"1=1";
		else
		{
			int  sqr = (int)sqrt(1.0*n);//n的根号
			//枚举根号n以内的质因子
			for(int i=0;i<pNum && prime[i] <= sqr;i++)
			{
				if(n % prime[i] == 0)//如果prime[i]是n的质因子
				{
					fac[num].x = prime[i];//记录该因子
					fac[num].cnt = 0;
					while(n % prime[i] == 0)//计算出质因子的个数
					{
						fac[num].cnt++;
						n /= prime[i];	
					} 
					num++;//不同质因子个数加一 
				}	
				if(n == 1)	break;//及时退出循环节省时间 
			}	
			if(n != 1)//如果无法被根号n以内的质因子除尽
			{
				fac[num].x = n;//那么一定有 一个 大于根号n的质因子
				fac[num++].cnt = 1;	
			}
			//按格式输出结果
			
			for(int i=0;i<num;i++)
			{
				result += fac[i].cnt;	
			} 
			cout<<result<<endl;
		} 
	}
	return 0;
}
*/

int main()
{
	int n;
	while(cin>>n)
	{
		int num = 0;
		for(int i=2;i<=sqrt(1.0*n);i++)
		{
			while(n % i == 0)
			{
				n /= i;
				num++;
			}
		}
		if(n!=1)
			num++;
		cout<<num<<endl;
	}
	return 0;
}



1948-Problem-D-约数的个数

题目链接:http://codeup.cn/problem.php?cid=100000592&pid=3
此题有时间限制的大坑:包括常规判断质数超时和使用cin和cout超时(应用printf)
还有一点:约数和定理:
约数和定理
对于一个大于1正整数n可以分解质因数:n=p1a1*p2a2*p3a3*…*pkak,
则由约数个数定理可知n的正约数有(a₁+1)(a₂+1)(a₃+1)…(ak+1)个,
那么n的(a₁+1)(a₂+1)(a₃+1)…(ak+1)个正约数的和为
f(n)=(p10+p11+p12+…p1a1)(p20+p21+p22+…p2a2)…(pk0+pk1+pk2+…pkak)

//1948-Problem-D-约数的个数
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 100010;

struct factor
{
	int x,cnt;//x为质因数,cnt为其个数 
}fac[10];

int prime[maxn],pNum=0;
bool p[maxn] = {false};

void Find_Prime()//素数筛
{
	for(int i=2;i<maxn;i++)
	{
		if(!p[i])
		{
			prime[pNum++]=i;	
			for(int j = i+i;j < maxn;j += i)
				p[j] = true;
		}	
	}	
} 

int main()
{
	Find_Prime();
	int N;
	while(scanf("%d",&N) && N)
	{
		while(N--)
		{
			int n;//输入n个整数 
			scanf("%d", &n);
			int num = 0;
			//枚举根号n以内的质因子
			for(int i=0;i<pNum && prime[i] <= sqrt(1.0*n);i++)
			{
				if(n % prime[i] == 0)//如果prime[i]是n的质因子
				{
					fac[num].x = prime[i];//记录该因子
					fac[num].cnt = 0;
					while(n % prime[i] == 0)//计算出质因子的个数
					{
						fac[num].cnt++;
						n /= prime[i];	
					} 
					num++;//不同质因子个数加一 
				}	
				if(n == 1)	break;//及时退出循环节省时间 
			}	
			if(n != 1)//如果无法被根号n以内的质因子除尽
			{
				fac[num].x = n;//那么一定有 一个 大于根号n的质因子
				fac[num++].cnt = 1;	
			}
			int facnum = 1;
			for(int i=0;i<num;i++)
			{//累乘所有质因数的个数+1
				facnum *= fac[i].cnt + 1; 
			}
			printf("%d\n",facnum);
		}
	}
	return 0;
}




1997-Problem-E-完数与盈数

题目链接: http://codeup.cn/problem.php?cid=100000592&pid=4

//1997-Problem-E-完数与盈数
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 100010;
//一个数如果恰好等于它的各因子(该数本身除外)子和
//1既不是质数也不是合数,用质因子素数打表不合适 

int sum(int num)//求数的除1外各因子之和 
{
	int sum = 0;
	for(int i=1;i<num;i++)
	{
		if(num % i == 0)
			sum+=i;
	}
	return sum;
}

int main()
{
	cout<<"E:";
	for(int i=2;i<=60;i++)
	{
		if(sum(i) == i)
			cout<<" "<<i;
	} 
	cout<<endl;
	cout<<"G:"; 
	for(int i=2;i<=60;i++)
	{
		if(sum(i) > i)
			cout<<" "<<i;
	} 
	cout<<endl;
	return 0;
}

总结

质因子分解就是将合数分解为素数之积(5.4节为素数),要注意灵活运用;
注意时间限制、约数和定理

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李霁明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值