一,题目
Description
读五年级的楠楠刚学完了质数、合数、因数、质因数等概念。
他还知道了每个合数都可以写成几个质数相乘的形式,其中每个质数都是这个合数的因数,叫做这个合数的质因数.把一个合数用质因数相乘的形式表示出来,叫做分解质因数.
聪明爱动脑筋的楠楠突然对具有互不相同的质因数的合数产生了兴趣。例如:
30=2 *3 * 5
它有互不相同的质因数
70 = 2 * 5 * 7,它也有互不相同的质因数。
若一个合数中所有的质因数互不相同,则把它称之为具有单纯质因数的合数。
他想知道还有哪些数是单纯质因数的合数。
你现在要帮楠楠解决的问题是:已知N,依次输出N以内所有具有单纯质因数的合数。
Input
输入数据只一个整数N(10<=N<=1000000)。
Output
依次输出N以内所有具有单纯质因数的合数。
Samples
输入数据 1
12
输出数据 1
6 10
二,解法
- 解法1(90分)
直接找题意模拟,枚举1~n,如果枚举2的数是质数则跳过,用一个变量fl记录该数是否为单纯质因数(一开始为1),再对枚举的数进行分解质因数,如果该数的某一个质因子分解时分解次数>1,就fl = 0,break;最后判断如果fl == 1,输出i即可。
#include <bits/stdc++.h>
using namespace std;
long long n,t,fl,s;
bool pri(int k)
{
for(long long i = 2; i <= k / i; i++)
if(k % i == 0)
return 0;
return 1;
}
int main()
{
scanf("%d",&n);
for(long long j = 1; j <= n; j++)
{
int kl = j;
if(pri(kl) == 1) continue;
fl = 1;
s = kl;
for(long long i = 2; i <= s / i; i++)
{
if(kl % i == 0)
{
kl /= i;
if(kl % i == 0)
{
fl = 0;
break;
}
}
}
if(fl == 1) cout<<j<<" ";
}
return 0;
}
2,解法2(100分)
用类似埃氏筛的思路。
step1:先用欧拉筛筛出1~n的质数,如果isp[i]==1说明i是质数,也就是不可能成为单纯质因数。并且注意上述过程结束后还要把isp[1]=1
step2 :枚举1~pris中的数,并用j储存i * i,然后因为此时j已经是个完全平方数了,他不可能再成为单纯质因数了,所以将1~n中所有j的倍数的isp设为1
step3:将1~n中所有isp[i]==0的i输出即可
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,pris,pri[10000010];
bool isp[10000010];
void prr(int b)
{
pris = 0;
memset(pri,0,sizeof(pri));
memset(isp,1,sizeof(isp));
isp[1] = 0;
for(long long i = 2; i <= b; i++)
{
if(isp[i] == 1) pri[++pris] = i;
for(long long j = 1; i * pri[j] <= b; j++)
{
isp[i * pri[j]] = 0;
if(i % pri[j] == 0) break;
}
}
memset(isp,0,sizeof(isp));
for(int i = 1;i <= pris;i++) isp[pri[i]] = 1;
isp[1] = 1;
}
signed main()
{
scanf("%lld",&n);
prr(n);
for(int i = 2;i <= pris;i++)
{
int j = i * i;
for(int k = 1;k * j <= n;k++) isp[k * j] = 1;
}
for(int i = 1;i <= n;i++)
if(isp[i] == 0)
printf("%lld ",i);
return 0;
}