numOfprime java_关于java:计算素数

以下是Codeforce上的问题

两名士兵在玩游戏。首先,他们选择一个正整数n并将其提供给第二个士兵。然后第二个尝试使最大回合数成为可能。每个回合包括选择一个正整数x≥1,这样n可以被x整除,然后将n替换为n≥1。当n等于1并且没有更多可能的有效动作时,游戏结束,第二名士兵的得分等于他执行的回合数。

为了使游戏更有趣,第一个士兵选择形式a!?/?b!中的n!对于一些正整数a和b(a≥≥b)。在这里乘k!我们表示k的阶乘定义为所有不大于k的正整数的乘积。

第二个士兵的最大可能分数是多少?

输入值

输入的第一行包括一个整数t(1≤t≤t≤1000 000 000),表示士兵玩游戏的次数。

然后跟随t行,每行包含一对整数a和b(1≤≤b≤≤a≤5≤000≤000)定义游戏的n值。

输出量

对于每个游戏输出,第二个士兵可获得的最大分数。

所以我试图计算n的素因数(如n的素因数分解)。

以下是我的代码,但在测试用例中失败

a = 5000000和b = 4999995

import java.util.Scanner;

import java.lang.*;

public class Main {

public static void main (String[] args) throws java.lang.Exception

{

// your code goes here

int count=0;

Scanner input=new Scanner(System.in);

int testcases=input.nextInt();

for(int m=1;m<=testcases;m++){

count=0;

long a=input.nextLong();

long b=input.nextLong();

double n=1;

for(double i=b+1;i

n=n*i;

//System.out.println(Math.sqrt(n));

for(int i=2;i

if(n%i==0){

while(n%i==0){

n=n/i;

count++;

}

}

}

if(n!=1) count++;

System.out.println(count);

}

}

}

在你的情况下,一个! / b! 是

3,124,993,750,004,374,998,750,000,120,000,000

比2 ^ 111大一点。 只有最大2 ^ 53的数字才能安全地表示为具有double值的整数。 如果使用long,则可以将其提高到2 ^ 63,但这还不够。

您必须使用BigInteger或必须更改方法:而不是除a的结果! / b! 分解为主要因子,将有助于析因的因子进行划分,然后合并主要因子集。

为了说明您的示例:

5000000 == 2^6 * 5^7

4999999 == 4999999

4999998 == 2 * 3 * 191 * 4363

4999997 == 43 * 116279

4999996 == 2^2 * 1249999

a! / b! == 2^9 * 3 * 5^7 * 43 * 191 * 4363 * 116279 * 1249999 * 4999999

由于a和b的输入很小,我们可以创建一个数组numOfPrime,该数组的索引为ith,

numOfPrime[i] = number of prime factor of i

因此,我们注意到numOfPrime[i] = 1 + numOfPrime[i/x]与x是i的任意素数。

为简单起见,假设x是i的最小素数,我们可以使用Eratosthenes筛子为每个i预先计算x

int[]x = new int[5000001];

for(int i = 2; i < x.length; i++)

if(x[i] == 0)

for(int j = i + i; j < x.length; j+= i)

if(x[j] == 0)

x[j] = i;

int[]numOfPrime = new int[5000001];

for(int i = 2; i < x.length; i++)

if(x[i] == 0)

numOfPrime[i] = 1;

else

numOfPrime[i] = 1 + numOfPrime[i/x[i]];

您可以看看我针对此问题提交的内容

基于@ m-oehm的答案:

int[] factors = new int[a-b];

for(int i=0;i

factors[i] = b+1+i;

boolean done = false;

int i = 2;

while(!done){

done = true;

for(int j=0; j

if(i>Math.sqrt(factors[j]) && factors[j]!=1){  // factors[j] is prime

factors[j] = 1;

count++;

}else{

while(factors[j]%i==0){   // divide factors[j] by i as many times as you can

factors[j]/=i;

count++;

}

}

if(factors[j]!=1)            // if all factors have reach 1, you're done

done = false;

}

i++;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值