前n个数的最大奇数除数之和

时间:2010-07-19 16:14:48

标签: algorithm math numbers

我最近一直在使用topcoder,我偶然发现了这个我无法理解的问题。 问题是找到给定“n”的F(n)= f(1)+ f(2)+ .... + f(n),使得f(n)是n的最大奇数除数。 答案有很多简单的解决方案;但是,我发现这个解决方案非常有趣。

int compute(n) {
if(n==0) return 0;
long k = (n+1)/2;
return k*k + compute(n/2);
}

但是,我不太明白如何从诸如此类的问题陈述中获取递归关系。有人可以帮忙吗?

4 个答案:

答案 0 :(得分:11)

我相信他们正在尝试使用以下事实:

  • f(2k + 1)= 2k + 1,即奇数的最大奇数除数就是数字本身。
  • f(2k)= f(k)。即偶数2m的最大奇数除数与数m的最大奇数除数相同。
  • 前k个奇数的和等于k ^ 2.

现在将{1,2,...,2m + 1}拆分为{1,3,5,7,...}和{2,4,6,...,2m}并尝试申请以上事实。

答案 1 :(得分:0)

我无法看到该算法如何能够解决您所描述的问题。 (我将假设“N”和“n”指的是同一个变量)。

鉴于n = 12。

最大奇数除数为3(其他除数为1,2,4,6和12)

F(12)因此f(1)+ f(2)+ f(3)或1 + 1 + 3或5.

使用此算法:

k =(12 + 1)/ 2或6

我们返回6 * 6 + f(6),或36 +某些不会为负数的数字。

答案 2 :(得分:0)

如果这是Java,我会说:

 import java.util.*;
 int sum_largest_odd_factors (int n){
      ArrayList<Integer> array = new ArrayList();//poorly named, I know
      array.add(1);
      for(int j = 2; j <= n; j++){
           array.add(greatestOddFactor(j));
      }
      int sum = 0;
      for(int i = 0; i < array.size(); i++){
           sum += array.get(i); 
      }
      return sum;
 }
 int greatestOddFactor(int n){
      int greatestOdd = 1;
      for(int i = n-((n%2)+1); i >= 1; i-=2){
          //i: starts at n if odd or n-1 if even 
          if(n%i == 0){
               greatestOdd = i;
               break;
               //stop when reach first odd factor b/c it's the largest
          }
      }
      return greatestOdd;
 }

这无疑是乏味的,可能是O(n ^ 2)操作,但每次都会有效。我会留给你翻译成C ++,因为Java和J是我可以使用的唯一语言(甚至是低级别的语言)。我很好奇其他人可以想出什么巧妙的算法来更快地做到这一点。

答案 3 :(得分:0)

如果你正在寻找所有奇数除数的总和,直到n ..

前n个数的所有奇数除数的总和

...

for(long long int i=1;i<=r;i=i+2)
{
    sum1=sum1+i*(r/i); 
}

for(long long int i=1;i<l;i=i+2)
{
    sum2=sum2+i*((l-1)/i); 
}

ans=sum1-sum2;;;

表示l到r

范围内所有除数的总和
        try
        {           
            FileSystem fs = FileSystem.get(config);
            StringBuilder builder=new StringBuilder();
            byte[] buffer=new byte[4096];
            int bytesRead;

            FSDataInputStream in = fs.open(new Path(fname));
            while ((bytesRead = in.read(buffer)) > 0) 
                builder.append(new String(buffer, 0, bytesRead));
            in.close();

            return builder.toString();
        }
        catch (IOException ex) 
        {
            ex.printStackTrace();
            return "";
        }

谢谢!!