zoj_2723 Semi-Prime 半素数

来源:互联网 发布:淘宝定制产品退货规则 编辑:程序博客网 时间:2024/05/17 08:04

题目链接:zoj_2723 Semi-Prime 半素数

       又是一道有关素数的题,这回找的是半素数,即除了1和本身外,只有两个素数因子。由于数据量大(2<N<1000 000),所以如果将每个测试数据都做因式分解,一定会出现超时错误。

       基本思路是建立一个[2,1000 000]范围内的半素数表,读入数据,直接检索。

       为了解决这个问题,我们继续使用造福人类的STL——vector & set,分别用来存储素数和半素数。为什么素数的存储不用set呢?因为我们的终极目标不是判断素数,而是半素数。采用vector存储素数有利于线性查找,在for循环中,可直接根据下标遍历素数表。而采用set存储半素数,是因为set是平衡检索二叉树,可以将元素自动排序,检索速度最快。

       这里再复习一下素数的判断方法:首先排除2以外的所有偶数,然后从奇数中排除素数的倍数,剩下的就是素数。

       注意:一个合数的最小素因子不超过它的平方根,这个可以做循环停止的条件。


代码:

#include <iostream>#include <vector>#include <set>#include <cmath>using namespace std;vector<int> v;set<int> s;void ChoosePrime(int a,int b)//建立[a,b]范围内的素数表{    for(int i=a;i<=b;i++)    {        //2是素数,这里清楚2的倍数        if(i!=2&&i%2==0) continue;        for(int j=3;j*j<=i;j+=2)        {            if(i%j==0) goto RL;        }        v.push_back(i);    RL:continue;    }}int main(){    ChoosePrime(2,500000);//建立[2,500000]范围内的素数表    int i,j,p;    for(i=0;i<v.size();i++)//建立[2,1000 000]范围内的半素数表    {        for(j=0;j<v.size();j++)        {            p=v[i]*v[j];//两个素数相乘            if(p<1000000) s.insert(p);            else break;        }    }    //读入数据,在半素数表中查找,看是否在该表中    int n;    set<int>::iterator it;    while(cin>>n)    {        it=s.find(n);        if(it!=s.end()) cout<<"Yes"<<endl;        else cout<<"No"<<endl;    }}


0 0
原创粉丝点击