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

Do your best to show the world what you are capable of

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.