给定数字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