Zumkelle Number
Last Updated :
24 Mar, 2023
Given an integer N, the task is to check if N is a Zumkelle Number
Zumkelle Number is a whose divisors can be partitioned into two sets with the same sum.
For example, 12 is a Zumkeller number because its divisors 1, 2, 3, 4, 6, 12, can be partitioned in the two sets {12, 2}, and {1, 3, 4, 6} with same sum 14.
Examples:
Input: N = 12
Output: Yes
Explanation:
12’s’ divisors 1, 2, 3, 4, 6, 12, can be partitioned
in the two sets {12, 2}, and {1, 3, 4, 6} with same sum 14.
Input: N = 26
Output: No
Approach: The idea is to store all the factors of the number in an array and then Finally, partition the array into two subsets such that the sum of elements in both the subset is same.
Partition problem for the same is explained in detail in this article:
Partition problem | DP-18
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void storeDivisors( int n, vector< int >& div )
{
for ( int i = 1; i <= sqrt (n); i++) {
if (n % i == 0) {
if (i == (n / i))
div .push_back(i);
else {
div .push_back(i);
div .push_back(n / i);
}
}
}
}
bool isPartitionPossible(vector< int >& arr)
{
int n = arr.size();
int sum = 0;
int i, j;
for (i = 0; i < n; i++)
sum += arr[i];
if (sum % 2 != 0)
return false ;
bool part[sum / 2 + 1][n + 1];
for (i = 0; i <= n; i++)
part[0][i] = true ;
for (i = 1; i <= sum / 2; i++)
part[i][0] = false ;
for (i = 1; i <= sum / 2; i++) {
for (j = 1; j <= n; j++) {
part[i][j] = part[i][j - 1];
if (i >= arr[j - 1])
part[i][j] = part[i][j] || part[i - arr[j - 1]][j - 1];
}
}
return part[sum / 2][n];
}
bool isZumkelleNum( int N)
{
vector< int > div ;
storeDivisors(N, div );
return isPartitionPossible( div );
}
int main()
{
int n = 12;
if (isZumkelleNum(n))
cout << "Yes" ;
else
cout << "No" ;
return 0;
}
|
Java
import java.util.*;
class GFG{
static void storeDivisors( int n,
Vector<Integer> div)
{
for ( int i = 1 ; i <= Math.sqrt(n); i++)
{
if (n % i == 0 )
{
if (i == (n / i))
div.add(i);
else
{
div.add(i);
div.add(n / i);
}
}
}
}
static boolean isPartitionPossible
(Vector<Integer> arr)
{
int n = arr.size();
int sum = 0 ;
int i, j;
for (i = 0 ; i < n; i++)
sum += arr.get(i);
if (sum % 2 != 0 )
return false ;
boolean [][]part = new boolean [sum / 2 + 1 ][n + 1 ];
for (i = 0 ; i <= n; i++)
part[ 0 ][i] = true ;
for (i = 1 ; i <= sum / 2 ; i++)
part[i][ 0 ] = false ;
for (i = 1 ; i <= sum / 2 ; i++) {
for (j = 1 ; j <= n; j++) {
part[i][j] = part[i][j - 1 ];
if (i >= arr.get(j - 1 ))
part[i][j] = part[i][j] ||
part[i - arr.get(j - 1 )][j - 1 ];
}
}
return part[sum / 2 ][n];
}
static boolean isZumkelleNum( int N)
{
Vector<Integer> div = new Vector<Integer>();
storeDivisors(N, div);
return isPartitionPossible(div);
}
public static void main(String[] args)
{
int n = 12 ;
if (isZumkelleNum(n))
System.out.print( "Yes" );
else
System.out.print( "No" );
}
}
|
Python3
def storeDivisors(n, div):
for i in range ( 1 , 1 + int (n * * 0.5 )):
if (n % i = = 0 ):
if (i = = int (n / i)):
div.append(i);
else :
div.append(i);
div.append( int (n / i));
def isPartitionPossible( arr):
n = len (arr);
sums = 0 ;
for i in range (n):
sums + = arr[i]
if (sums % 2 ! = 0 ):
return False ;
part = [];
for i in range ( 0 , 1 + int (sums / 2 )):
ll = [];
for j in range (n + 1 ):
ll.append( False );
part.append(ll);
for i in range ( 1 + n):
part[ 0 ][i] = True ;
for i in range ( 1 , 1 + int (sums / 2 )):
part[i][ 0 ] = False ;
for i in range ( 1 , 1 + int (sums / 2 )):
for j in range ( 1 , 1 + n):
part[i][j] = part[i][j - 1 ];
if (i > = arr[j - 1 ]):
part[i][j] = part[i][j] or part[i - arr[j - 1 ]][j - 1 ];
return 1 ;
def isZumkelleNum(N):
div = [];
storeDivisors(N, div);
return isPartitionPossible(div);
N = 12 ;
if (isZumkelleNum(N)):
print ( "Yes" );
else :
print ( "No" );
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void storeDivisors( int n,
List< int > div)
{
for ( int i = 1; i <= Math.Sqrt(n); i++)
{
if (n % i == 0)
{
if (i == (n / i))
div.Add(i);
else
{
div.Add(i);
div.Add(n / i);
}
}
}
}
static bool isPartitionPossible
(List< int > arr)
{
int n = arr.Count;
int sum = 0;
int i, j;
for (i = 0; i < n; i++)
sum += arr[i];
if (sum % 2 != 0)
return false ;
bool [,]part = new bool [sum / 2 + 1, n + 1];
for (i = 0; i <= n; i++)
part[0, i] = true ;
for (i = 1; i <= sum / 2; i++)
part[i, 0] = false ;
for (i = 1; i <= sum / 2; i++)
{
for (j = 1; j <= n; j++)
{
part[i, j] = part[i, j - 1];
if (i >= arr[j - 1])
part[i, j] = part[i, j] ||
part[i - arr[j - 1],
j - 1];
}
}
return part[sum / 2, n];
}
static bool isZumkelleNum( int N)
{
List< int > div = new List< int >();
storeDivisors(N, div);
return isPartitionPossible(div);
}
public static void Main(String[] args)
{
int n = 12;
if (isZumkelleNum(n))
Console.Write( "Yes" );
else
Console.Write( "No" );
}
}
|
Javascript
<script>
function storeDivisors(n, div)
{
for ( var i = 1; i <= Math.sqrt(n); i++) {
if (n % i == 0) {
if (i == Math.floor(n / i))
div.push(i);
else {
div.push(i);
div.push(Math.floor(n / i));
}
}
}
}
function isPartitionPossible( arr)
{
var n = arr.length;
var sum = 0;
var i, j;
for (i = 0; i < n; i++)
sum += arr[i];
if (sum % 2 != 0)
return false ;
var part = [];
for (i = 0; i <= Math.floor(sum / 2); i++) {
var ll = [];
for (j = 0; j <= n; j++) {
ll.push( false );
}
part.push(ll);
}
for (i = 0; i <= n; i++)
part[0][i] = true ;
for (i = 1; i <= Math.floor(sum / 2); i++)
part[i][0] = false ;
for (i = 1; i <= Math.floor(sum / 2); i++) {
for (j = 1; j <= n; j++) {
part[i][j] = part[i][j - 1];
if (i >= arr[j - 1])
part[i][j] = part[i][j] || part[i - arr[j - 1]][j - 1];
}
}
return 1;
}
function isZumkelleNum(N)
{
var div = [];
storeDivisors(N, div);
return isPartitionPossible(div);
}
var N = 12;
if (isZumkelleNum(N))
document.write( "Yes" );
else
document.write( "No" );
</script>
|
Output:
Yes
Time Complexity: O(N * sum)
Reference: OEIS
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...