我有一个编程竞赛即将到来,我正在解决去年的问题作为比赛的修改,我遇到了一个简单的程序,但它需要数学,不幸的是我很擅长。
以下是问题:
给定正整数 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);
}
}
感谢任何帮助。
答案 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;
}
}