Semiperfect Number
Last Updated :
12 Oct, 2023
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=40
Input: 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++
#include <bits/stdc++.h>
using namespace std;
vector< int > factors( int n)
{
vector< int > v;
v.push_back(1);
for ( int i = 2; i <= sqrt (n); i++) {
if (n % i == 0) {
v.push_back(i);
if (n / i != i) {
v.push_back(n / i);
}
}
}
return v;
}
bool check( int n)
{
vector< int > v;
v = factors(n);
sort(v.begin(), v.end());
int r = v.size();
bool subset[r + 1][n + 1];
for ( int i = 0; i <= r; i++)
subset[i][0] = true ;
for ( int i = 1; i <= n; i++)
subset[0][i] = false ;
for ( int i = 1; i <= r; i++) {
for ( int j = 1; j <= n; j++) {
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 ((subset[r][n]) == 0)
return false ;
else
return true ;
}
int main()
{
int n = 40;
if (check(n))
cout << "Yes" ;
else
cout << "No" ;
return 0;
}
|
Java
import java.util.*;
class GFG{
static Vector<Integer> factors( int n)
{
Vector<Integer> v = new Vector<>();
v.add( 1 );
for ( int i = 2 ; i <= Math.sqrt(n); i++)
{
if (n % i == 0 )
{
v.add(i);
if (n / i != i)
{
v.add(n / i);
}
}
}
return v;
}
static boolean check( int n)
{
Vector<Integer> v = new Vector<>();
v = factors(n);
Collections.sort(v);
int r = v.size();
boolean [][]subset =
new boolean [r + 1 ][n + 1 ];
for ( int i = 0 ; i <= r; i++)
subset[i][ 0 ] = true ;
for ( int i = 1 ; i <= n; i++)
subset[ 0 ][i] = false ;
for ( int i = 1 ; i <= r; i++)
{
for ( int j = 1 ; j <= n; j++)
{
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 ((subset[r][n]) == false )
return false ;
else
return true ;
}
public static void main(String[] args)
{
int n = 40 ;
if (check(n))
System.out.print( "Yes" );
else
System.out.print( "No" );
}
}
|
Python3
import math
def factors( n):
v = []
v.append( 1 )
sqt = int (math.sqrt(n))
for i in range ( 2 , sqt + 1 ):
if (n % i = = 0 ):
v.append(i)
if (n / / i ! = i):
v.append(n / / i)
return v
def check( n):
v = []
v = factors(n)
v.sort()
r = len (v)
subset = [[ 0 for i in range (n + 1 )]
for j in range (r + 1 )]
for i in range (r + 1 ):
subset[i][ 0 ] = True
for i in range ( 1 , n + 1 ):
subset[ 0 ][i] = False
for i in range ( 1 , r + 1 ):
for j in range ( 1 , n + 1 ):
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 ((subset[r][n]) = = 0 ):
return False
else :
return True
if __name__ = = "__main__" :
n = 40
if (check(n)):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
using System.Collections.Generic;
class GFG{
static List< int > factors( int n)
{
List< int > v = new List< int >();
v.Add(1);
for ( int i = 2;
i <= Math.Sqrt(n); i++)
{
if (n % i == 0)
{
v.Add(i);
if (n / i != i)
{
v.Add(n / i);
}
}
}
return v;
}
static bool check( int n)
{
List< int > v = new List< int >();
v = factors(n);
v.Sort();
int r = v.Count;
bool [,]subset = new bool [r + 1,
n + 1];
for ( int i = 0; i <= r; i++)
subset[i, 0] = true ;
for ( int i = 1; i <= n; i++)
subset[0, i] = false ;
for ( int i = 1; i <= r; i++)
{
for ( int j = 1; j <= n; j++)
{
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 ((subset[r, n]) == false )
return false ;
else
return true ;
}
public static void Main(String[] args)
{
int n = 40;
if (check(n))
Console.Write( "Yes" );
else
Console.Write( "No" );
}
}
|
Javascript
<script>
function factors(n)
{
let v = [];
v.push(1);
for (let i = 2; i <= Math.sqrt(n); i++)
{
if (n % i == 0)
{
v.push(i);
if (Math.floor(n / i) != i)
{
v.push(Math.floor(n / i));
}
}
}
return v;
}
function check(n)
{
let v = [] ;
v = factors(n);
v.sort( function (a,b){ return a-b;});
let r = v.length;
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 ;
}
}
for (let i = 0; i <= r; i++)
subset[i][0] = true ;
for (let i = 1; i <= n; i++)
subset[0][i] = false ;
for (let i = 1; i <= r; i++)
{
for (let j = 1; j <= n; j++)
{
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 ((subset[r][n]) == false )
return false ;
else
return true ;
}
let n = 40;
if (check(n))
document.write( "Yes" );
else
document.write( "No" );
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
vector< int > factors( int n)
{
vector< int > v;
v.push_back(1);
int sqrtN = sqrt (n);
for ( int i = 2; i <= sqrtN; i++) {
if (n % i == 0) {
v.push_back(i);
if (n / i != i) {
v.push_back(n / i);
}
}
}
return v;
}
bool check( int n)
{
vector< int > v;
v = factors(n);
sort(v.begin(), v.end());
int r = v.size();
vector< bool > subset(n + 1, false );
subset[0] = true ;
for ( int i = 0; i < r; i++) {
for ( int j = n; j >= v[i]; j--) {
subset[j] = subset[j] || subset[j - v[i]];
}
}
return subset[n];
}
int main()
{
int n = 40;
if (check(n))
cout << "Yes" ;
else
cout << "No" ;
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.Collections;
public class Main {
static ArrayList<Integer> factors( int n) {
ArrayList<Integer> v = new ArrayList<>();
v.add( 1 );
int sqrtN = ( int ) Math.sqrt(n);
for ( int i = 2 ; i <= sqrtN; i++) {
if (n % i == 0 ) {
v.add(i);
if (n / i != i) {
v.add(n / i);
}
}
}
return v;
}
static boolean check( int n) {
ArrayList<Integer> v;
v = factors(n);
Collections.sort(v);
int r = v.size();
boolean [] subset = new boolean [n + 1 ];
subset[ 0 ] = true ;
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 subset[n];
}
public static void main(String[] args) {
int n = 40 ;
if (check(n))
System.out.println( "Yes" );
else
System.out.println( "No" );
}
}
|
Python3
import math
def factors(n):
v = [ 1 ]
sqrtN = int (math.sqrt(n))
for i in range ( 2 , sqrtN + 1 ):
if n % i = = 0 :
v.append(i)
if n / / i ! = i:
v.append(n / / i)
return v
def check(n):
v = []
v = factors(n)
v.sort()
r = len (v)
subset = [ False ] * (n + 1 )
subset[ 0 ] = True
for i in range (r):
for j in range (n, v[i] - 1 , - 1 ):
subset[j] = subset[j] or subset[j - v[i]]
return subset[n]
if __name__ = = "__main__" :
n = 40
if check(n):
print ( "Yes" )
else :
print ( "No" )
|
C#
using System;
using System.Collections.Generic;
class Program
{
static List< int > Factors( int n)
{
List< int > factorsList = new List< int >();
factorsList.Add(1);
int sqrtN = ( int )Math.Sqrt(n);
for ( int i = 2; i <= sqrtN; i++)
{
if (n % i == 0)
{
factorsList.Add(i);
if (n / i != i)
{
factorsList.Add(n / i);
}
}
}
return factorsList;
}
static bool CheckSemiPerfect( int n)
{
List< int > factorsList = new List< int >();
factorsList = Factors(n);
factorsList.Sort();
int r = factorsList.Count;
bool [] subset = new bool [n + 1];
subset[0] = true ;
for ( int i = 0; i < r; i++)
{
for ( int j = n; j >= factorsList[i]; j--)
{
subset[j] = subset[j] || subset[j - factorsList[i]];
}
}
return subset[n];
}
static void Main()
{
int n = 40;
if (CheckSemiPerfect(n))
Console.WriteLine( "Yes" );
else
Console.WriteLine( "No" );
}
}
|
Javascript
function factors(n) {
const v = [1];
const sqrtN = Math.sqrt(n);
for (let i = 2; i <= sqrtN; i++) {
if (n % i === 0) {
v.push(i);
if (n / i !== i) {
v.push(n / i);
}
}
}
return v;
}
function check(n) {
let v = [];
v = factors(n);
v.sort((a, b) => a - b);
const r = v.length;
const subset = Array(n + 1).fill( false );
subset[0] = true ;
for (let i = 0; i < r; i++) {
for (let j = n; j >= v[i]; j--) {
subset[j] = subset[j] || subset[j - v[i]];
}
}
return subset[n];
}
const n = 40;
if (check(n)) {
console.log( "Yes" );
} else {
console.log( "No" );
}
|
Time Complexity: O(number of factors * N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...