您的位置:首页 > 其它

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

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

//新的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;
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: