在数论中,半完美数或伪完美数是自然数n,它等于其所有或某些适当除数的和。等于其所有适当除数之和的半完美数是一个理想数。
给定一个数字,任务是检查该数字是否为半完美数字。
例子:
Input: 40
Output: The number is Semiperfect
1+4+5+10+20=40
Input: 70
Output: The number is not Semiperfect
The first few semiperfect numbers are
6, 12, 18, 20, 24, 28, 30, 36, 40
方法:将所有数量因子存储在数据结构(向量或数组)中。按升序对它们进行排序。一旦存储了因子,就可以使用动态编程来检查是否有任何组合形式为N。该问题变得类似于“子集总和问题”。我们可以使用相同的方法并检查数字是否为半完美数字。
下面是上述方法的实现。
C++
// C++ program to check if the number
// is semi-perfect or not
#include
using namespace std;
// code to find all the factors of
// the number excluding the number itself
vector factors(int n)
{
// vector to store the factors
vector v;
v.push_back(1);
// note that this loop runs till sqrt(n)
for (int i = 2; i <= sqrt(n); i++) {
// if the value of i is a factor
if (n % i == 0) {
v.push_back(i);
// condition to check the
// divisor is not the number itself
if (n / i != i) {
v.push_back(n / i);
}
}
}
// return the vector
return v;
}
// Function to check if the
// number is semi-perfecr or not
bool check(int n)
{
vector v;
// find the divisors
v = factors(n);
// sorting the vector
sort(v.begin(), v.end());
int r = v.size();
// subset to check if no is semiperfect
bool subset[r + 1][n + 1];
// initialising 1st column to true
for (int i = 0; i <= r; i++)
subset[i][0] = true;
// initializing 1st row except zero position to 0
for (int i = 1; i <= n; i++)
subset[0][i] = false;
// loop to find whether the number is semiperfect
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= n; j++) {
// calculation to check if the
// number can be made by summation of diviors
if (j < v[i - 1])
subset[i][j] = subset[i - 1][j];
else {
subset[i][j] = subset[i - 1][j] ||
subset[i - 1][j - v[i - 1]];
}
}
}
// if not possible to make the
// number by any combination of divisors
if ((subset[r][n]) == 0)
return false;
else
return true;
}
// driver code to check if possible
int main()
{
int n = 40;
if (check(n))
cout << "Yes";
else
cout << "No";
return 0;
}
Java
// Java program to check
// if the number is
// semi-perfect or not
import java.util.*;
class GFG{
// Code to find all the factors of
// the number excluding the number itself
static Vector factors(int n)
{
// vector to store the factors
Vector v = new Vector<>();
v.add(1);
// note that this loop runs till Math.sqrt(n)
for (int i = 2; i <= Math.sqrt(n); i++)
{
// if the value of i is a factor
if (n % i == 0)
{
v.add(i);
// condition to check the
// divisor is not the number itself
if (n / i != i)
{
v.add(n / i);
}
}
}
// return the vector
return v;
}
// Function to check if the
// number is semi-perfecr or not
static boolean check(int n)
{
Vector v = new Vector<>();
// find the divisors
v = factors(n);
// sorting the vector
Collections.sort(v);
int r = v.size();
// subset to check if no
// is semiperfect
boolean [][]subset =
new boolean[r + 1][n + 1];
// initialising 1st column to true
for (int i = 0; i <= r; i++)
subset[i][0] = true;
// initializing 1st row except
// zero position to 0
for (int i = 1; i <= n; i++)
subset[0][i] = false;
// loop to find whether the
// number is semiperfect
for (int i = 1; i <= r; i++)
{
for (int j = 1; j <= n; j++)
{
// calculation to check if the
// number can be made by
// summation of diviors
if (j < v.elementAt(i - 1))
subset[i][j] = subset[i - 1][j];
else
{
subset[i][j] = subset[i - 1][j] ||
subset[i - 1][j - v.elementAt(i - 1)];
}
}
}
// If not possible to make the
// number by any combination of divisors
if ((subset[r][n]) == false)
return false;
else
return true;
}
// Driver code to check if possible
public static void main(String[] args)
{
int n = 40;
if (check(n))
System.out.print("Yes");
else
System.out.print("No");
}
}
// This code is contributed by gauravrajput1
Python3
# Python3 program to check if the number
# is semi-perfect or not
import math
# code to find all the factors of
# the number excluding the number itself
def factors( n):
# vector to store the factors
v = []
v.append(1)
# note that this loop runs till sqrt(n)
sqt = int(math.sqrt(n))
for i in range(2, sqt + 1):
# if the value of i is a factor
if (n % i == 0):
v.append(i)
# condition to check the
# divisor is not the number itself
if (n // i != i):
v.append(n // i)
# return the vector
return v
# Function to check if the
# number is semi-perfecr or not
def check( n):
v = []
# find the divisors
v = factors(n)
# sorting the vector
v.sort()
r = len(v)
# subset to check if no is semiperfect
subset = [[ 0 for i in range(n + 1)]
for j in range(r + 1)]
# initialising 1st column to true
for i in range(r + 1):
subset[i][0] = True
# initializing 1st row except zero position to 0
for i in range(1, n + 1):
subset[0][i] = False
# loop to find whether the number is semiperfect
for i in range(1, r + 1):
for j in range(1, n + 1):
# calculation to check if the
# number can be made by summation of diviors
if (j < v[i - 1]):
subset[i][j] = subset[i - 1][j];
else:
subset[i][j] = (subset[i - 1][j] or
subset[i - 1][j - v[i - 1]])
# if not possible to make the
# number by any combination of divisors
if ((subset[r][n]) == 0):
return False
else:
return True
# Driver Code
if __name__ == "__main__":
n = 40
if (check(n)):
print("Yes")
else:
print("No")
# This code is contributed by ChitraNayal
C#
// C# program to check
// if the number is
// semi-perfect or not
using System;
using System.Collections.Generic;
class GFG{
// Code to find all the
// factors of the number
// excluding the number itself
static List factors(int n)
{
// vector to store the factors
List v = new List();
v.Add(1);
// note that this loop runs
// till Math.Sqrt(n)
for (int i = 2;
i <= Math.Sqrt(n); i++)
{
// if the value of i is
// a factor
if (n % i == 0)
{
v.Add(i);
// condition to check the
// divisor is not the number
// itself
if (n / i != i)
{
v.Add(n / i);
}
}
}
// return the vector
return v;
}
// Function to check if the
// number is semi-perfecr or not
static bool check(int n)
{
List v = new List();
// find the divisors
v = factors(n);
// sorting the vector
v.Sort();
int r = v.Count;
// subset to check if no
// is semiperfect
bool [,]subset = new bool[r + 1,
n + 1];
// initialising 1st column
// to true
for (int i = 0; i <= r; i++)
subset[i, 0] = true;
// initializing 1st row except
// zero position to 0
for (int i = 1; i <= n; i++)
subset[0, i] = false;
// loop to find whether the
// number is semiperfect
for (int i = 1; i <= r; i++)
{
for (int j = 1; j <= n; j++)
{
// calculation to check if the
// number can be made by
// summation of diviors
if (j < v[i - 1])
subset[i, j] = subset[i - 1, j];
else
{
subset[i, j] = subset[i - 1, j] ||
subset[i - 1, (j - v[i - 1])];
}
}
}
// If not possible to make
// the number by any combination
// of divisors
if ((subset[r, n]) == false)
return false;
else
return true;
}
// Driver code
public static void Main(String[] args)
{
int n = 40;
if (check(n))
Console.Write("Yes");
else
Console.Write("No");
}
}
// This code is contributed by Princi Singh
输出:
Yes
时间复杂度: O(因子数量* N)
辅助空间: O(因数* N)