寻找最大质因数(质因数分解+剪枝)

寻找最大质因数

题目描述:
给出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;
}
posted @ 2016-10-16 16:03  抽空的太阳  阅读(665)  评论(0编辑  收藏  举报