一个使用Java解决日志数学概率的程序

时间:2014-04-03 18:52:11

标签: java function math

我有一个编程竞赛即将到来,我正在解决去年的问题作为比赛的修改,我遇到了一个简单的程序,但它需要数学,不幸的是我很擅长。

以下是问题:

  

给定正整数 n ,找到奇数 o 并且   非负整数 p ,使 n = o2 ^ p o 乘以2   权力 p

     

输入文件的第一行只包含一个正整数    d 等于测试用例的数量, 1< = d< = 10 。数据集如下。每个数据集只包含一行   恰好一个整数 n,1< = n< = 10 ^ 6

     

示例输出

     

2 //测试用例数量的数值
  24 // n的值   27 // n的值

     

样品输出
  3 3 //前3是o的值,第2 3是p的值   7 7 //第一个7是o的值,第二个7是p的值

     

" //"部分不应该在输出或输入

这就是我到目前为止所做的一切,除了我需要使用公式正确解决的公式外,我把一切都搞定了

public static void main(String[] args) {

    double n = 0, d = 0, o = 0, p = 0;

    double x = 1;

    //START INPUT
    Scanner input = new Scanner(System.in);
    //input d, number of times program repeats

    System.out.println("Please enter the number of times you want to run the test(no more than 10)");
    d = input.nextDouble();

    //check the validity of d
    while((d > 10) || (d<1)){
        System.out.println("Invalid input");
         System.out.println("Enter another value for d");
         d = input.nextDouble();
    }



    while(x <= d){

            x++;

            System.out.println("enter a value for n");
            n = input.nextDouble();
    //check the validity of n
        while((n > 1000000) || (n<1)){
            System.out.println("Invalid input.");
            System.out.println("Enter Another Value for n");
            n = input.nextDouble();
        }
        //Calculates
        p = Math.log(n) / Math.log(2.0);
        o = n / Math.pow(p, 2);
    //STOP CALCULATE

    //PRINTS    
        System.out.println(o + " " + p);
        }

    }

感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

您需要做的就是反复划分2:

function removeTwo(n)
    o, p := n, 0
    while o % 2 == 0
        o, p := o/2, p+1
    return o, p

我会留给你翻译成Java。

答案 1 :(得分:0)

许多不同的方式。对于编程竞赛,当数量很少时,我通常采用一种简单的方法:暴力!也许不是你问题的完美答案,但在比赛中做其他任务时要记住:工作是否足够好,选择你能想到的第一个解决方案并尝试实施它。至少在我参加的大多数比赛中都是这样,在给定的时间范围内尽可能多地完成任务。

对于公式 n = o2 p o 奇数和 p &gt; 0,1&lt; = n &lt; = 10 6 , 我们可以看到2 p 总是至少 2。 这意味着o应该低于n的一半,所以我们只需要搜索o的值高达我们给出的值的一半。我们只需要检查奇数值。

然后可以为所选择的o尝试不同的p值。如果结果高于n,我们应该尝试o的下一个值。

javacode:

public void calc(int n) {
    for (int o = 1; o <= n / 2; o += 2) {
        int p = 1;
        while (true) {
            int test = o * (int) Math.pow(2, p);
            if (test == n) { // solution found
                System.out.println("o:" + o + ", p:" + p);
                return;
            }
            if (test > n) break; // total value too high, lets start with another o
            p++;
        }
    }
}

在输入n = 24时逐步执行此操作:
o = 1,p = 1 =&gt; 2
o = 1,p = 2 =&gt; 4
o = 1,p = 3 =&gt; 8
o = 1,p = 4 =&gt; 16个
o = 1,p = 5 =&gt; 32,太高了,试试另一个o
o = 3,p = 1 =&gt; 6
o = 3,p = 2 =&gt; 12个
o = 3,p = 3 =&gt; 24,TADA!

不同的暴力方法可能是以p的值开始,或者用n p 的不同值除以n,直到得到一个奇整数。

答案 2 :(得分:0)

这个问题实际上并不涉及太多的数学问题。相当有点笨拙。

有助于知道每个值2 ^ p等于(1<<p)。知道了这一点,您可以先计算n中设置的最高位。例如

n = 24 =  11000 (binary) : Highest bit is 4
n = 36 : 100100 (binary) : Highest bit is 5

然后你可以从这个位位置开始作为p的候选者,减小这个值直到你发现方程是可解的。当您达到零时,输入值n必须是奇数。如果需要,可以在开始时明确地检测到这一点。

import java.util.Arrays;

public class FindFactors
{
    public static void main(String[] args)
    {
        for (int n=0; n<100; n++)
        {
            System.out.println("For "+n+" : "+Arrays.toString(findFactors(n)));
        }
    }

    private static int[] findFactors(int n)
    {
        int p = highestBit(n);
        while (p >= 0)
        {
            int twoPowP = (1 << p);
            int c = n / twoPowP;
            if (c * twoPowP == n)
            {
                return new int[]{c,p};
            }
            p--;
        }
        return null;
    }

    private static int highestBit(int n)
    {
        int b = 0;
        while (n > 1)
        {
            n >>= 1;
            b++;
        }
        return b;
    }
}