📜  等分序列

📅  最后修改于: 2021-05-04 23:37:49             🧑  作者: Mango

给定数字n,任务是打印其等分序列。数字的等分序列以其自身开头,序列的其余项为前一个项的适当除数的总和。例如,10的等分序列为10、8、7、1、0。该序列可以重复。例如,对于6,我们有一个全为6的无限序列。在这种情况下,我们将打印重复号码并停止。

例子:

Input:  n = 10
Output: 10 8 7 1 0
Sum of proper divisors of 10 is  5 + 2 + 1 = 8.
Sum of proper divisors of 8 is 4 + 2 + 1 = 7.
Sum of proper divisors of 7 is 1
Sum of proper divisors of 1 is 0
Note that there is no proper divisor of 1.

Input  : n = 6
Output : 6 
         Repeats with 6

Input : n = 12
Output : 12 16 15 9 4 3 1 0 

重要事项:

  • 重复的等分序列长度为1的数字称为“完美数字”。例如,6的适当除数之和为6。
  • 长度为2的等份重复序列的数字称为可和数字。例如220是可联系电话。
  • 具有重复的等分序列长度为3的数字称为社交数字。
  • 据推测,每个等分序列都以下列方式之一结束
    • 质数依次为1和0的质数。
    • 一个完美的数字
    • 一组友善或友善的数字。

解决方案主要在于计算上一项的所有适当除数之和。

  • 如果我们仔细观察,数字n的除数是成对出现的。例如,如果n = 100,则所有对数除数为:(1,100),(2,50),(4,25),(5,20),(10,10)
  • 利用这一事实可以有效地计算除数。在检查除数时,我们必须注意是否存在两个相等的除数,例如(10,10)。
  • 在这种情况下,我们在计算总和时将只采用其中之一。该总和将包含所有可能除数的总和,因此我们必须从所有除数的总和中减去数字n才能得到适当除数的总和。

我们可以通过首先打印数字n,然后使用适当的除数之和来计算下一项来生成序列。当我们计算下一个术语时,我们检查是否已经看到过这个术语。如果该术语再次出现,则说明我们有重复的序列。我们打印相同的内容并打破循环。

C++
// C++ implementation of Optimized approach
// to generate Aliquot Sequence
#include 
using namespace std;
  
// Function to calculate sum of all proper divisors
int getSum(int n)
{
    int sum = 0;  // 1 is a proper divisor
  
    // Note that this loop runs till square root
    // of n
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i==0)
        {
            // If divisors are equal, take only one
            // of them
            if (n/i == i)
                sum = sum + i;
  
            else // Otherwise take both
            {
                sum = sum + i;
                sum = sum + (n / i);
            }
        }
    }
  
    // calculate sum of all proper divisors only
    return sum - n;
}
  
// Function to print Aliquot Sequence for an input n.
void printAliquot(int n)
{
    // Print the first term
    printf("%d ", n);
    unordered_set  s;
    s.insert(n);
  
    int next = 0;
    while (n > 0)
    {
        // Calculate next term from previous term
        n = getSum(n);
  
        if (s.find(n) != s.end())
        {
            cout << "\nRepeats with " << n;
            break;
        }
  
        // Print next term
        cout << n << " ";
        s.insert(n);
    }
}
  
/* Driver program to test above function */
int main()
{
    printAliquot(12);
    return 0;
}


Java
// Java implementation of Optimized approach 
// to generate Aliquot Sequence 
import java.util.*;
  
class GFG 
{
  
    // Function to calculate sum 
    // of all proper divisors 
    static int getSum(int n) 
    {
        int sum = 0; // 1 is a proper divisor 
  
        // Note that this loop runs till  
        // square root of n 
        for (int i = 1; i <= Math.sqrt(n); i++)
        {
            if (n % i == 0) 
            {
                // If divisors are equal, take only one 
                // of them 
                if (n / i == i) 
                {
                    sum = sum + i;
                }
                else // Otherwise take both 
                {
                    sum = sum + i;
                    sum = sum + (n / i);
                }
            }
        }
  
        // calculate sum of all proper divisors only 
        return sum - n;
    }
  
    // Function to print Aliquot 
    // Sequence for an input n. 
    static void printAliquot(int n) 
    {
          
        // Print the first term 
        System.out.printf("%d ", n);
          
        TreeSet s = new TreeSet<>();
        s.add(n);
  
        int next = 0;
        while (n > 0) 
        {
            // Calculate next term from previous term 
            n = getSum(n);
  
            if (s.contains(n) && n != s.last()) 
            {
                System.out.print("\nRepeats with " + n);
                break;
            }
  
            // Print next term 
            System.out.print(n + " ");
            s.add(n);
        }
    }
  
    /* Driver code */
    public static void main(String[] args) 
    {
        printAliquot(12);
    }
}
  
// This code is contributed by Rajput-JI


Python3
# Python implementation of Optimized approach
# to generate Aliquot Sequence
  
from math import sqrt
  
# Function to calculate sum of all proper divisors
def getSum(n):
    summ = 0 # 1 is a proper divisor
  
    # Note that this loop runs till square root
    # of n
    for i in range(1, int(sqrt(n)) + 1):
        if n % i == 0:
  
            # If divisors are equal, take only one
            # of them
            if n // i == i:
                summ += i
  
            # Otherwise take both
            else:
                summ += i
                summ += n // i
  
    # calculate sum of all proper divisors only
    return summ - n
  
# Function to print Aliquot Sequence for an input n.
def printAliquot(n):
  
    # Print the first term
    print(n, end=" ")
    s = set()
    s.add(n)
  
    nextt = 0
    while n > 0:
  
        # Calculate next term from previous term
        n = getSum(n)
  
        if n in s:
            print("Repeats with", n)
            break
  
        # Print next term
        print(n, end=" ")
        s.add(n)
  
# Driver Code
if __name__ == "__main__":
    printAliquot(12)
  
# This code is contributed by
# sanjeev2552


C#
// C# implementation of Optimized approach 
// to generate Aliquot Sequence 
using System;
using System.Collections.Generic;
  
class GFG 
{ 
  
    // Function to calculate sum 
    // of all proper divisors 
    static int getSum(int n) 
    { 
        int sum = 0; // 1 is a proper divisor 
  
        // Note that this loop runs till 
        // square root of n 
        for (int i = 1; i <= Math.Sqrt(n); i++) 
        { 
            if (n % i == 0) 
            { 
                // If divisors are equal,  
                // take only one of them 
                if (n / i == i) 
                { 
                    sum = sum + i; 
                } 
                else // Otherwise take both 
                { 
                    sum = sum + i; 
                    sum = sum + (n / i); 
                } 
            } 
        } 
  
        // calculate sum of all proper divisors only 
        return sum - n; 
    } 
  
    // Function to print Aliquot 
    // Sequence for an input n. 
    static void printAliquot(int n) 
    { 
          
        // Print the first term 
        Console.Write(n+" "); 
          
        HashSet s = new HashSet(); 
        s.Add(n); 
  
        while (n > 0) 
        { 
              
            // Calculate next term from previous term 
            n = getSum(n); 
  
            if (s.Contains(n)) 
            { 
                Console.Write("\nRepeats with " + n); 
                break; 
            } 
  
            // Print next term 
            Console.Write(n + " "); 
            s.Add(n); 
        } 
    } 
  
    /* Driver code */
    public static void Main(String[] args) 
    { 
        printAliquot(12); 
    } 
} 
  
/* This code has been contributed 
by PrinciRaj1992*/


输出:

12 16 15 9 4 3 1 0 

参考:
https://zh.wikipedia.org/wiki/Aliquot_sequence