【问题标题】:Sum of the largest odd divisors of the first n numbers前 n 个数的最大奇数除数之和
【发布时间】:2010-07-19 16:14:47
【问题描述】:

我最近一直在研究 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);
}

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

【问题讨论】:

  • fcompute 这里是同一个东西吗?
  • @Aakash:不,他们不是(如果正确的话),我已经编辑了这个问题。
  • 您有一个错字:您使用的是“N”和“n”,请修正
  • @Jason :感谢您的指出!我已经解决了。

标签: algorithm math numbers


【解决方案1】:

我相信他们试图利用以下事实:

  • 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} 并尝试应用以上事实。

【讨论】:

    【解决方案2】:

    您也可以使用动态方法,也可以使用辅助空格

    int sum=0;
    int a[n+1];
    for(int i=1;i<=n;i++){
      if(i%2!=0)
      a[i] = i;
      else
      a[i] = a[i/2];
    }
    for(int i=1;i<=n;i++){
      sum+=a[i];
    }
    cout<<sum;
    

    当数字为奇数时,数字本身将是最大的奇数除数,a[i] 将存储它的值,当数字为偶数时,a[number/2] 将存储在 a[i] 中,因为对于偶数 number/2 的最大奇数除数将是该数的最大奇数除数。

    也可以使用以下三种情况解决合计。

    【讨论】:

      【解决方案3】:

      我看不出该算法如何解决您描述的问题。 (我假设“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 + 某个不会为负 31 的数字。

      【讨论】:

      • 问题中的代码错误,我已经编辑了代码以使其正确。 (请参阅我的答案以了解原因)。
      【解决方案4】:

      如果这是 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 是我可以使用的唯一语言(甚至是低级语言)。我很好奇其他人能想出什么巧妙的算法来加快速度。

      【讨论】:

        【解决方案5】:

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

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

        ...

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

        对于 l 到 r 范围内所有除数的总和

        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;;;
        

        谢谢!!

        【讨论】:

          猜你喜欢
          • 2016-03-07
          • 1970-01-01
          • 2020-10-02
          • 2021-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-28
          • 1970-01-01
          相关资源
          最近更新 更多