【算法学习笔记】82.素数生成 数据范围利用 SJTU OJ 1020 分解质因数

更新...最后发现根本不用在循环中判断是否是素数, 因为先除的肯定是素数, 后面的以该素数的倍数组成的合数早就被除没了.....

//新的build() 注意最后一位的处理

void build(){
    
    int sq = sqrt(ori);
    int i;
    for (i = 2; i <= sq + 1; ++i)
    {
        // if( (i<50000 and isPrime(i)) or(i>=50000)){
        bool ok = false;
        while(todo % i == 0){
            ok = true;
            todo = todo / i;
            n[len]++;
        }
        if(ok){
            primeNums[len] = i;
            len++;
        }
    }
    if(todo>=sq+1){
        primeNums[len] = todo;
        n[len]++;
        len++;
    }
}

 

 

 

 

///早期的sb代码

虽然是水题,但是被坑了n多次...一开始超时..以为是判断素数的效率问题, 后来用了生成素数表的方法, 变成了RE 这才知道不是这个问题.

注意到数据范围是在2^31内的, 根据Hint可知 大于 sqrt(a)的a的质因数只有一个.

那么对于一个很大的数, 那个很大的质因数肯定就是它自己,就不要对其进行判断了.

生成素数表的代码如下:

void generatePrimes(){
    memset(bePrime,true,sizeof(bePrime));
    bePrime[2] = true;
    for (int i = 2; i < 50000;i++)
    {
        if(!bePrime[i]){
            for (int j = 2*i; j < 50000; j+=i) 
                bePrime[j] = false; 
        }
    }
}
生成素数表

主要思想是先假设所有的数都是素数,然后把每一个素数的所有倍数都判否(注意要顺序)就可以了,但是实际上对于效率的提升貌似不高。。。。

核心代码很简单, 需要注意的是那个神奇的if条件, 完美的避开了这个问题...

void build(){

    for (int i = 2; i <= todo; ++i)
    { 
        if( (i<50000 and isPrime(i)) or(i>=50000)){
            bool ok = false;
            while(todo % i == 0){
                ok = true;
                todo = todo / i;
                n[len]++;
            }
            if(ok){
                primeNums[len] = i;
                len++;
                if(i*i>ori){
                    break;
                }
            }
        }
    }
}

 

posted @ 2015-07-22 15:29  雨尘之林  阅读(452)  评论(0编辑  收藏  举报