Distinct powers of a number N such that the sum is equal to K
Last Updated :
24 Nov, 2021
Given two numbers N and K, the task is to print the distinct powers of N which are used to get the sum K. If it’s not possible, print -1.
Examples:
Input: N = 3, K = 40
Output: 0, 1, 2, 3
Explanation:
The value of N is 3.
30 + 31 + 32 + 33 = 40
Input: N = 4, K = 65
Output: 0, 3
The value of N is 4.
40 + 43 = 65
Input: N = 4, K = 18
Output: -1
Explanation:
It’s impossible to get 18 by adding the power of 4.
Observation: One observation that needs to be made for any arbitrary number a is that there can’t exist a number greater than aK if all the powers of a from 0 to k-1 are added by using each power at most once.
Example: Let a = 3 and K = 4. Then:
34 = 81.
30 + 31 + 32 + 33 = 40 which is less than 81(34).
Naive Approach: By using the above observation, the naive approach can be formed. The idea is to continuously subtract the highest power of N not exceeding K from K until K reaches 0. If at any instance, K becomes equal to some power that was already subtracted from it previously, then it’s not possible to get the sum equal to K. Therefore, an array is used to keep track of powers that have been subtracted from K.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int highestPower( int n, int k)
{
int i = 0;
int a = pow (n, i);
while (a <= k) {
i += 1;
a = pow (n, i);
}
return i - 1;
}
int b[50] = { 0 };
int PowerArray( int n, int k)
{
while (k) {
int t = highestPower(n, k);
if (b[t]) {
cout << -1;
return 0;
}
else
b[t] = 1;
k -= pow (n, t);
}
for ( int i = 0; i < 50; i++) {
if (b[i]) {
cout << i << ", " ;
}
}
}
int main()
{
int N = 3;
int K = 40;
PowerArray(N, K);
return 0;
}
|
Java
class GFG{
static int highestPower( int n, int k)
{
int i = 0 ;
int a = ( int ) Math.pow(n, i);
while (a <= k) {
i += 1 ;
a = ( int ) Math.pow(n, i);
}
return i - 1 ;
}
static int b[] = new int [ 50 ];
static int PowerArray( int n, int k)
{
while (k> 0 ) {
int t = highestPower(n, k);
if (b[t]> 0 ) {
System.out.print(- 1 );
return 0 ;
}
else
b[t] = 1 ;
k -= Math.pow(n, t);
}
for ( int i = 0 ; i < 50 ; i++) {
if (b[i] > 0 ) {
System.out.print(i+ ", " );
}
}
return 0 ;
}
public static void main(String[] args)
{
int N = 3 ;
int K = 40 ;
PowerArray(N, K);
}
}
|
Python3
from math import pow
def highestPower(n,k):
i = 0
a = pow (n, i)
while (a < = k):
i + = 1
a = pow (n, i)
return i - 1
b = [ 0 for i in range ( 50 )]
def PowerArray(n, k):
while (k):
t = highestPower(n, k)
if (b[t]):
print ( - 1 )
return 0
else :
b[t] = 1
k - = pow (n, t)
for i in range ( 50 ):
if (b[i]):
print (i,end = ', ' )
if __name__ = = '__main__' :
N = 3
K = 40
PowerArray(N, K)
|
C#
using System;
public class GFG{
static int highestPower( int n, int k)
{
int i = 0;
int a = ( int ) Math.Pow(n, i);
while (a <= k) {
i += 1;
a = ( int ) Math.Pow(n, i);
}
return i - 1;
}
static int []b = new int [50];
static int PowerArray( int n, int k)
{
while (k > 0) {
int t = highestPower(n, k);
if (b[t] > 0) {
Console.Write(-1);
return 0;
}
else
b[t] = 1;
k -= ( int )Math.Pow(n, t);
}
for ( int i = 0; i < 50; i++) {
if (b[i] > 0) {
Console.Write(i+ ", " );
}
}
return 0;
}
public static void Main(String[] args)
{
int N = 3;
int K = 40;
PowerArray(N, K);
}
}
|
Javascript
<script>
function highestPower(n, k)
{
let i = 0;
let a = Math.pow(n, i);
while (a <= k) {
i += 1;
a = Math.pow(n, i);
}
return i - 1;
}
let b = Array.from({length: 50}, (_, i) => 0);
function PowerArray(n, k)
{
while (k>0) {
let t = highestPower(n, k);
if (b[t]>0) {
document.write(-1);
return 0;
}
else
b[t] = 1;
k -= Math.pow(n, t);
}
for (let i = 0; i < 50; i++) {
if (b[i] > 0) {
document.write(i+ ", " );
}
}
return 0;
}
let N = 3;
let K = 40;
PowerArray(N, K);
</script>
|
Time Complexity: O((log N)2)
- Time taken to find out the power is Log(N).
- On top of that, another Log(N) loop is being used for K.
- So, the overall time complexity is Log(N)2
Auxiliary Space: O(50)
Efficient Approach: Another observation that can be made is that for K to be the sum of N’s powers which can be used only once, K % N either has to be 1 or 0 (1 because of N0). Therefore, if (K % N) comes out anything other than 0 or 1, it can be concluded that it is impossible to get the sum K.
Therefore, by using the above observations, the following steps can be followed to compute the answer:
- First, a counter is initialized with 0.
- If (K % N) = 0, then the counter is incremented by 1, and K is updated to K/N.
- If K % N = 1, then the frequency array f[count] is incremented by 1, and K is updated to K – 1.
- If, at any point, this f[count] becomes more than 1, then return -1(because the same power can’t be used twice).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int b[50] = { 0 };
int PowerArray( int n, int k)
{
int count = 0;
while (k) {
if (k % n == 0) {
k /= n;
count++;
}
else if (k % n == 1) {
k -= 1;
b[count]++;
if (b[count] > 1) {
cout << -1;
return 0;
}
}
else {
cout << -1;
return 0;
}
}
for ( int i = 0; i < 50; i++) {
if (b[i]) {
cout << i << ", " ;
}
}
}
int main()
{
int N = 3;
int K = 40;
PowerArray(N, K);
return 0;
}
|
Java
class GFG{
static int b[] = new int [ 50 ];
static int PowerArray( int n, int k)
{
int count = 0 ;
while (k > 0 )
{
if (k % n == 0 )
{
k /= n;
count++;
}
else if (k % n == 1 )
{
k -= 1 ;
b[count]++;
if (b[count] > 1 )
{
System.out.print(- 1 );
return 0 ;
}
}
else
{
System.out.print(- 1 );
return 0 ;
}
}
for ( int i = 0 ; i < 50 ; i++)
{
if (b[i] != 0 )
{
System.out.print(i + ", " );
}
}
return Integer.MIN_VALUE;
}
public static void main(String[] args)
{
int N = 3 ;
int K = 40 ;
PowerArray(N, K);
}
}
|
Python3
b = [ 0 for i in range ( 50 )]
def PowerArray(n, k):
count = 0
while (k):
if (k % n = = 0 ):
k / / = n
count + = 1
elif (k % n = = 1 ):
k - = 1
b[count] + = 1
if (b[count] > 1 ):
print ( - 1 )
return 0
else :
print ( - 1 )
return 0
for i in range ( 50 ):
if (b[i]):
print (i,end = "," )
if __name__ = = '__main__' :
N = 3
K = 40
PowerArray(N, K)
|
C#
using System;
class GFG{
static int []b = new int [50];
static int PowerArray( int n, int k)
{
int count = 0;
while (k > 0)
{
if (k % n == 0)
{
k /= n;
count++;
}
else if (k % n == 1)
{
k -= 1;
b[count]++;
if (b[count] > 1)
{
Console.Write(-1);
return 0;
}
}
else
{
Console.Write(-1);
return 0;
}
}
for ( int i = 0; i < 50; i++)
{
if (b[i] != 0)
{
Console.Write(i + ", " );
}
}
return int .MinValue;
}
public static void Main(String[] args)
{
int N = 3;
int K = 40;
PowerArray(N, K);
}
}
|
Javascript
<script>
let b = new Array(50);
b.fill(0);
function PowerArray(n, k)
{
let count = 0;
while (k > 0)
{
if (k % n == 0)
{
k = parseInt(k / n, 10);
count++;
}
else if (k % n == 1)
{
k -= 1;
b[count]++;
if (b[count] > 1)
{
document.write(-1);
return 0;
}
}
else
{
document.write(-1);
return 0;
}
}
for (let i = 0; i < 50; i++)
{
if (b[i] != 0)
{
document.write(i + ", " );
}
}
return Number.MIN_VALUE;
}
let N = 3;
let K = 40;
PowerArray(N, K);
</script>
|
Time Complexity: Since the highest power is not checked every time, the running time of this algorithm is log(N).
Auxiliary Space: O(50)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...