In number theory, a semiperfect number or pseudoperfect number is a natural number n that is equal to the sum of all or some of its proper divisors. A semiperfect number that is equal to the sum of all its proper divisors is a perfect number.
Given a number, the task is to check if the number is a semi-perfect number or not.
Examples:
Input: 40
Output: The number is Semiperfect
1+4+5+10+20=40Input: 70
Output: The number is not Semiperfect
The first few semiperfect numbers are
6, 12, 18, 20, 24, 28, 30, 36, 40
Approach: Store all the factors of the number in a data-structure(Vector or Arrays). Sort them in increasing order. Once the factors are stored, Dynamic programming can be used to check if any combination forms N or not. The problem becomes similar to the Subset Sum Problem. We can use the same approach and check if the number is a semi-perfect number or not.
Below is the implementation of the above approach.
// C++ program to check if the number // is semi-perfect or not #include <bits/stdc++.h> using namespace std;
// code to find all the factors of // the number excluding the number itself vector< int > factors( int n)
{ // vector to store the factors
vector< int > 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-perfect or not bool check( int n)
{ vector< int > 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 divisors
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 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<Integer> factors( int n)
{ // vector to store the factors
Vector<Integer> 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-perfect or not static boolean check( int n)
{ Vector<Integer> 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 divisors
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 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-perfect 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 divisors
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# 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< int > factors( int n)
{ // vector to store the factors
List< int > v = new List< int >();
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-perfect or not static bool check( int n)
{ List< int > v = new List< int >();
// 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 divisors
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 |
<script> // Javascript program to check // if the number is // semi-perfect or not // Code to find all the factors of // the number excluding the number itself function factors(n)
{ // vector to store the factors
let v = [];
v.push(1);
// note that this loop runs till Math.sqrt(n)
for (let i = 2; i <= Math.sqrt(n); i++)
{
// if the value of i is a factor
if (n % i == 0)
{
v.push(i);
// condition to check the
// divisor is not the number itself
if (Math.floor(n / i) != i)
{
v.push(Math.floor(n / i));
}
}
}
// return the vector
return v;
} // Function to check if the // number is semi-perfect or not function check(n)
{ let v = [] ;
// find the divisors
v = factors(n);
// sorting the vector
v.sort( function (a,b){ return a-b;});
let r = v.length;
// subset to check if no
// is semiperfect
let subset = new Array(r + 1);
for (let i=0;i<r+1;i++)
{
subset[i]= new Array(n+1);
for (let j=0;j<n+1;j++)
{
subset[i][j]= false ;
}
}
// initialising 1st column to true
for (let i = 0; i <= r; i++)
subset[i][0] = true ;
// initializing 1st row except
// zero position to 0
for (let i = 1; i <= n; i++)
subset[0][i] = false ;
// loop to find whether the
// number is semiperfect
for (let i = 1; i <= r; i++)
{
for (let j = 1; j <= n; j++)
{
// calculation to check if the
// number can be made by
// summation of divisors
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 to check if possible let n = 40; if (check(n))
document.write( "Yes" );
else document.write( "No" );
// This code is contributed by rag2127 </script> |
Yes
Time Complexity: O(number of factors * N)
Auxiliary Space: O(number of factors * N)
Efficient approach : Space optimization
In previous approach the current value subset[i][j] is only depend upon the current and previous row values of subset matrix. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation:
// C++ program to check if the number // is semi-perfect or not #include <bits/stdc++.h> using namespace std;
// code to find all the factors of // the number excluding the number itself vector< int > factors( int n)
{ // vector to store the factors
vector< int > v;
v.push_back(1);
// note that this loop runs till sqrt(n)
int sqrtN = sqrt (n);
for ( int i = 2; i <= sqrtN; 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-perfect or not bool check( int n)
{ vector< int > v;
// find the divisors
v = factors(n);
// sorting the vector
sort(v.begin(), v.end());
int r = v.size();
// initialize to store computations of subproblems
vector< bool > subset(n + 1, false );
// Base Case
subset[0] = true ;
// iterate over subproblems to get the current
// value from previous computations
for ( int i = 0; i < r; i++) {
for ( int j = n; j >= v[i]; j--) {
subset[j] = subset[j] || subset[j - v[i]];
}
}
// return final answer
return subset[n];
} // Driver Code int main()
{ int n = 40;
if (check(n))
cout << "Yes" ;
else
cout << "No" ;
return 0;
} |
import java.util.ArrayList;
import java.util.Collections;
public class Main {
// Function to find all the factors of the number excluding the number itself
static ArrayList<Integer> factors( int n) {
// ArrayList to store the factors
ArrayList<Integer> v = new ArrayList<>();
v.add( 1 );
// Note that this loop runs till sqrt(n)
int sqrtN = ( int ) Math.sqrt(n);
for ( int i = 2 ; i <= sqrtN; 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 ArrayList of factors
return v;
}
// Function to check if the number is semi-perfect or not
static boolean check( int n) {
ArrayList<Integer> v;
// Find the divisors
v = factors(n);
// Sorting the ArrayList
Collections.sort(v);
int r = v.size();
// Initialize an array to store computations of subproblems
boolean [] subset = new boolean [n + 1 ];
// Base Case
subset[ 0 ] = true ;
// Iterate over subproblems to get the current
// value from previous computations
for ( int i = 0 ; i < r; i++) {
for ( int j = n; j >= v.get(i); j--) {
subset[j] = subset[j] || subset[j - v.get(i)];
}
}
// Return the final answer
return subset[n];
}
// Driver Code
public static void main(String[] args) {
int n = 40 ;
if (check(n))
System.out.println( "Yes" );
else
System.out.println( "No" );
}
} |
import math
# Function to find all the factors of # the number excluding the number itself def factors(n):
# List to store the factors
v = [ 1 ]
# Note that this loop runs till sqrt(n)
sqrtN = int (math.sqrt(n))
for i in range ( 2 , sqrtN + 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 list
return v
# Function to check if the # number is semi-perfect or not def check(n):
v = []
# Find the divisors
v = factors(n)
# Sorting the list
v.sort()
r = len (v)
# Initialize to store computations of subproblems
subset = [ False ] * (n + 1 )
# Base Case
subset[ 0 ] = True
# Iterate over subproblems to get the current
# value from previous computations
for i in range (r):
for j in range (n, v[i] - 1 , - 1 ):
subset[j] = subset[j] or subset[j - v[i]]
# Return final answer
return subset[n]
# Driver Code if __name__ = = "__main__" :
n = 40
if check(n):
print ( "Yes" )
else :
print ( "No" )
|
using System;
using System.Collections.Generic;
class Program
{ // Function to find all the factors of the number excluding the number itself
static List< int > Factors( int n)
{
// List to store the factors
List< int > factorsList = new List< int >();
factorsList.Add(1);
// Note that this loop runs until sqrt(n)
int sqrtN = ( int )Math.Sqrt(n);
for ( int i = 2; i <= sqrtN; i++)
{
// If the value of i is a factor
if (n % i == 0)
{
factorsList.Add(i);
// Condition to check that the divisor is not the number itself
if (n / i != i)
{
factorsList.Add(n / i);
}
}
}
// Return the list
return factorsList;
}
// Function to check if the number is semi-perfect or not
static bool CheckSemiPerfect( int n)
{
List< int > factorsList = new List< int >();
// Find the divisors
factorsList = Factors(n);
// Sorting the list
factorsList.Sort();
int r = factorsList.Count;
// Initialize an array to store computations of subproblems
bool [] subset = new bool [n + 1];
// Base Case
subset[0] = true ;
// Iterate over subproblems to get the current value from previous computations
for ( int i = 0; i < r; i++)
{
for ( int j = n; j >= factorsList[i]; j--)
{
subset[j] = subset[j] || subset[j - factorsList[i]];
}
}
// Return the final answer
return subset[n];
}
// Driver Code
static void Main()
{
int n = 40;
if (CheckSemiPerfect(n))
Console.WriteLine( "Yes" );
else
Console.WriteLine( "No" );
}
} // This code is contributed by shivamgupta0987654321 |
// Function to find all the factors of a number excluding the number itself function factors(n) {
const v = [1]; // Array to store the factors
const sqrtN = Math.sqrt(n);
for (let i = 2; i <= sqrtN; i++) {
// If i is a factor
if (n % i === 0) {
v.push(i);
// Check if the divisor is not the number itself
if (n / i !== i) {
v.push(n / i);
}
}
}
// Return the array of factors
return v;
} // Function to check if the number is semi-perfect or not function check(n) {
let v = [];
// Find the divisors
v = factors(n);
// Sort the array
v.sort((a, b) => a - b);
const r = v.length;
// Initialize an array to store computations of subproblems
const subset = Array(n + 1).fill( false );
// Base Case
subset[0] = true ;
// Iterate over subproblems to get the current
// value from previous computations
for (let i = 0; i < r; i++) {
for (let j = n; j >= v[i]; j--) {
subset[j] = subset[j] || subset[j - v[i]];
}
}
// Return the final answer
return subset[n];
} // Driver Code const n = 40; if (check(n)) {
console.log( "Yes" );
} else {
console.log( "No" );
} |
Yes
Time Complexity: O(number of factors * N)
Auxiliary Space: O(N)