寻找最大质因数
题目描述:
给出N个数字,试求质因数最大的数字。
输入描述:
第一行,一个整数N,表示数字个数。
接下来N行,每行一个整数ai,表示给出的数字。
输出描述:
一个整数,表示质因数最大的数字。(如果有多个最大相同,则输出最后输入那一个)
样例输入:
4
35
60
40
42
样例输出:
42
数据范围及提示:
N≤10^6,2≤ai≤10^6
用cin可能会导致超时
思路:
先用艾氏筛法筛出数据范围内的质数,然后对于读入的每个数x进行判断。
加速:
1、读入优化
2、剪枝
(1)、x的质因数一定小于等于小于x的第一个质数,即:35的质因数一定小于等于31
(2)、如果x的某个质因数已经小于已知的最大质因数,那么没有必要再对x质因数查找。
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1000010;
int n,tot,a,f_max,f_ans,c[maxn],prime[maxn];
bool flag[maxn];
int init()//读入优化
{
int p=0;char c=getchar();
if(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9')
{
p=p*10+c-'0';
c=getchar();
}
return p;
}
void prepare()
{
for(int i=2;i<=maxn;i++)
if(!flag[i])
{
prime[++tot]=i;
c[i]=tot;
for(int j=i+i;j<=maxn;j+=i)
flag[j]=1;
}
}
void work(int x)
{
int st;
for(int i=x;i>=1;i--)//剪枝:x的质因数一定小于等于小于x的第一个质数
if(!flag[i])
{
st=c[i];
break;
}
for(int i=st;i>=f_max;i--)//剪枝:继续质因数查找的条件:x的质因数大于已知的最大质因数
if(x%prime[i]==0)//对于x找到它最大的质因数
{
f_ans=x;//更新答案
f_max=i;//更新最大质因数
return;//返回
}
}
int main()
{
prepare();
n=init();
for(int i=1;i<=n;i++)
{
a=init();
work(a);
}
cout<<f_ans;//输出答案
return 0;
}
更快的方法:
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1000010;
int n,tot,a,f_max=1,f_ans,c[maxn],prime[maxn];
bool flag[maxn];
int init()
{
int p=0;char c=getchar();
if(c>'9'||c<'0')c=getchar();
while(c>='0'&&c<='9')
{
p=p*10+c-'0';
c=getchar();
}
return p;
}
void prepare()
{
for(int i=2;i<=maxn;i++)
if(!flag[i])
{
prime[++tot]=i;
for(int j=i+i;j<=maxn;j+=i)
flag[j]=1;
}
}
void work(int x)
{
for(int i=f_max;i<=tot;i++)
{
if(prime[i]>x) return;
if(x%prime[i]==0)
{
f_ans=x;
f_max=i;
}
}
}
int main()
{
prepare();
n=init();
for(int i=1;i<=n;i++)
{
a=init();
work(a);
}
cout<<f_ans;
return 0;
}