zoukankan      html  css  js  c++  java
  • 寻找最大质因数(质因数分解+剪枝)

    寻找最大质因数

    题目描述:
    给出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;
    }
  • 相关阅读:
    LeetCode 139. Word Break
    Amazon behavior question
    学习笔记之100 TOP Ikm C++ Online Test Questions
    学习笔记之IKM C++ 11
    学习笔记之C/C++指针使用常见的坑
    LeetCode 208. Implement Trie (Prefix Tree)
    队列 & 栈//岛屿的个数
    队列 & 栈//设计循环队列
    队列 & 栈//设计循环队列
    查找表类算法//存在重复元素 III
  • 原文地址:https://www.cnblogs.com/cax1165/p/6070915.html
Copyright © 2011-2022 走看看