算法训练 素因子去重 c语言,【蓝桥杯】算法训练 素因子去重

算法训练 素因子去重

时间限制:1.0s   内存限制:256.0MB

问题描述

给定一个正整数n,求一个正整数p,满足p仅包含n的所有素因子,且每个素因子的次数不大于1

输入格式

一个整数,表示n

输出格式

输出一行,包含一个整数p。

样例输入

1000

样例输出

10

数据规模和约定

n<=10^12

样例解释:n=1000=2^3*5*3,p=2*5=10

题目还是很好理解的,一看到题,我的第一个思路就是先打印素数表,然后直接用整数的质因子分解来做,结果是耗时15ms,内存984.0KB。关于这两个过程可以戳以前的博客:埃氏筛法打印素数表   算术基本定理:整数质因子分解

1 #include

2 using namespace std;

3

4 bool is_prime[10005];

5 int prime[10005];

6 void sieve(int n){

7 int p = 0;

8 for(int i = 2; i <= n; i++) is_prime[i] = true;

9 for(int i = 2; i <= n; i++){

10 if(is_prime[i]){

11 prime[p++] = i;

12 for(int j = 2*i; j<=n; j+=i) is_prime[j] = false;

13 }

14 }

15 }

16

17 int main(int argc, char *argv[]) {

18 sieve(10005);

19 long long n, ans = 1;

20 cin>>n;

21 for(int i = 0;prime[i]*prime[i]<=n; i++){

22 if(n % prime[i] == 0){

23 ans *= prime[i];

24 while(n % prime[i] == 0) n /= prime[i];

25 }

26 }

27 ans *= n;

28 cout<

29

30 return 0;

31 }

后来发现自己把题目理解复杂了,下面给出我的第二个思路,耗时46ms,内存936.0KB。

1 #include

2 using namespace std;

3

4 int main(int argc, char *argv[]) {

5 long long n, ans = 1;

6 cin>>n;

7 for(int k = 2; n != 1; k++){

8 if(n % k == 0){

9 ans = ans * k;

10 while(n % k == 0) n /= k;

11 }

12 }

13 cout<

14

15 return 0;

16 }

这个方法也很直接,从最小的质数2开始循环,判断当前的数k能不能整除n,如果可以就说明k是n的一个质因数,让ans乘上k,再让n除以k直到n不再包含k为止。每次循环k++。有个巧妙的地方在于,因为每次循环结束得到的新的n都已经不再包含上一个质因子k,所以下一次满足整除条件的k一定还是质数(有一点埃氏筛法的感觉)。比如取n=1000,它最小的质因子是2,在k=2的这一轮循环结束后,新的n为125,已经不再包含2,所以k=4时,n已经不再能被4整除,直接进入下一轮循环k=5。这一轮结束后,n=1,说明所有的质因子已经被找到,循环结束。

第三种方法是在网上看到的题解,我在循环那边优化了一下,也很简单直接,有一个素性判断的is_prime函数,然后直接循环判断质因子。下面是代码,耗时0ms,内存936.0KB。

1 #include

2 using namespace std;

3

4 bool is_prime(long long n){ //判断n是否为素数

5 for(long long i = 2; i*i <=n; i++)

6 if(n%i ==0) return false;

7 return true;

8 }

9

10 int main(int argc, char *argv[]) {

11 long long n, m = 1;

12 cin>>n;

13 for(long long i = 2; i*i<=n; i++){

14 if(n%i == 0 && is_prime(i)){

15 m *= i;

16 while(n%i==0) n/=i;

17 }

18 }

19 m *= n;

20 cout<

21

22 return 0;

23 }

最后一种也大同小异,用到了集合set元素,网上看到的题解。耗时46ms,内存932.0KB。(其实几种都差不多)

1 #include

2 #include

3 using namespace std;

4

5 set s;

6 bool isPrime(long long n){

7 for(int i=2; i*i <= n; i++)

8 if(n%i == 0) return false;

9 return true;

10 }

11

12 int main(){

13 long long n, ans=1;

14 cin>>n;

15 for(int i=2; n!=1; i++)

16 if(n%i==0 && isPrime(i)){

17 s.insert(i);

18 while(n%i==0) n/=i;

19 }

20 for(set::iterator it=s.begin(); it!=s.end(); it++)

21 ans *= (*it);

22 cout<

23

24 return 0;

25 }

标签:prime,int,因子,long,蓝桥,算法,ans,include

来源: https://www.cnblogs.com/Aikoin/p/10371719.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值