"方程"对hackerrank的挑战

时间:2014-09-07 05:04:38

标签: java

我在hackerrank.com上对“方程式”挑战的一些测试用例上遇到了麻烦。 这就是问题的所在:https://www.hackerrank.com/challenges/equations 我很确定我理解逻辑,但我的程序中仍然存在错误(或者我的逻辑中存在缺陷)。

public class Solution
{
    public static void mark(boolean[] a, int i, int n) //sieve util
    {
        int num = i*2;
        while(num <= n)        
        {
            a[num] = true;
            num += i;
        }
    }
    public static long legendre(int n, int p) //get prime power   
    {
        long ans = 0;
        int k = p;
        while(n/k != 0)        
        {
            ans += (long)n/k;
            k *= p;
        }
        return ans;
    }
    public static void main(String[] args)
    {
       long mod = 1000007; 
       int n;
       Scanner input = new Scanner(System.in);
       n = input.nextInt();
       boolean[] a = new boolean[n+1];
       for(int i = 2; i <= n; ++i) //sieve
       {
           if(a[i] == false)
           {
               mark(a,i,n);
           }
       }      
       boolean isEven = true;
       long ans = 1, power = 1;
       for(int i = 2; i <= n; ++i)
       {
           if(a[i] == false)
           {
               power = legendre(n,i);
               if(power%2 == 1)
               {
                   isEven = false;
               }
               ans *= (2*power+1);
               ans %= mod;
           }
       }
       if(isEven == true) //symmetric solution
            ans -= 1;
       if(n == 1) //special case
            System.out.println(1);
       else
            System.out.println(ans);                  
    }
}

我尝试做的事情:创建一个素数值表,然后获得每个素数因子n的幂。我使用了这个公式:http://www.cut-the-knot.org/blue/LegendresTheorem.shtml。我的程序为n = 105387(629416)产生了正确的输出,但是对于n = 131399,我的输出是598995 (应该是856428)。

此问题在此之前也有人问过:Sample testcase for Interviewstreet: Equations 有人问“N = 131399的输出是什么,我得到的是598995,但它给出了错误。 - peeyush 12月22日20:33” 显然我的特定错误不是唯一的。

2 个答案:

答案 0 :(得分:1)

调用legendre(131399,46349)时,变量k会溢出。

将此变量的类型从int更改为long


顺便说一句,你可以通过在循环中添加一个断言来轻松跟踪它:

if (k < 0)
    System.out.println(k);

答案 1 :(得分:0)

改变为长期以来的工作,我只是尝试过。你需要使用BigInteger。

查看我的解决方案......

public class Solutions {

    static boolean isPrime(int p) {
        boolean num = false;
        if (p == 2 || p == 3) {
            return true;
        }
        for (int j = 2; j <= Math.sqrt(p); j++) {
            if (p % j == 0) {
                num = false;
                break;
            } else {
                num = true;
            }
        }
        return num;
    }

    public static void main(String[] args) {
        long mod = 1000007;
        int n;
        Scanner input = new Scanner(System.in);
        n = input.nextInt();
        BigInteger bresult = BigInteger.ONE;
        long x = n;
        for (int i = 2; i <= x; i++) {
            if (isPrime(i)) {
                int k = 1;
                long power = 0;
                while ((Math.pow(i, k) <= x)) {

                    power += n / Math.pow(i, k);

                    k++;
                }
                bresult = bresult.multiply(BigInteger.valueOf(power * 2 + 1));
            }

        }
        System.out.println(bresult.mod(BigInteger.valueOf(mod)));

    }
}