Semiperfect Number

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 th 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.

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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-perfecr 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;
  
    // initialing 1st row except zero position to 0
    for (int i = 1; i <= n; i++)
        subset[0][i] = false;
  
    // loop to find whther 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;
}

chevron_right


Output:

Yes

Time Complexity: O(number of factors * N)
Auxiliary Space: O(number of factors * N)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.