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

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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.

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

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.