Generate an array of K elements such that sum of elements is N and the condition a[i] < a[i+1] <= 2*a[i] is met | Set 2

Given two integers N and K, the task is to generate an array arr[] of length K such that:

  1. arr[0] + arr[1] + … + arr[K – 1] = N.
  2. arr[i] > 0 for 0 ≤ i < K.
  3. arr[i] < arr[i + 1] ≤ 2 * arr[i] for 0 ≤ i < K – 1.

If there are multiple answers find any one of them, otherwise, print -1.

Examples:



Input: N = 26, K = 6
Output: 1 2 3 4 6 10
The above array satisfies all the conditions.

Input: N = 8, k = 3
Output: -1

Approach: Initially we form the array with the lowest possible configuration which is filling up the array with 1, 2, 3, 4.. which satisfies the given conditions. If the summation of 1..K is greater than N, then the array cannot be formed. In order to form the array, fill up the array initially with 1, 2, 3, .. K. Again add (n-sum)/k to every element in the array, because in adding so, no conditions are void, because we are adding equal elements to every number.

The remaining number rem is greedily added from the back, to make every number twice of its previous number. After filling up the array, if any of the given conditions are not met, print -1, else the formed array will be our desired answer.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function that print the
// desired array which
// satisfies the given conditions
void solve(int n, int k)
{
  
    int mini = 0;
    int x1 = 1;
    int a[k];
    for (int i = 1; i <= k; i++) {
        mini += x1;
        a[i - 1] = x1;
        x1 += 1;
    }
  
    // If the lowest filling condition
    // is void, then it is not possible to
    // generate the required array
    if (n < mini) {
        cout << "-1";
        return;
    }
  
    int rem = n - mini;
    int cnt = rem / k;
    rem = rem % k;
  
    // Increase all the elements by cnt
    for (int i = 0; i < k; i++)
        a[i] += cnt;
  
    // Start filling from the back
    // till the number is a[i+1] <= 2*a[i]
    for (int i = k - 1; i > 0 && rem > 0; i--) {
  
        // Get the number to be filled
        int xx = a[i - 1] * 2;
        int left = xx - a[i];
  
        // If it is less than the
        // remaining numbers to be filled
        if (rem >= left) {
            a[i] = xx;
            rem -= left;
        }
  
        // less than remaining numbers
        // to be filled
        else {
            a[i] += rem;
            rem = 0;
        }
    }
  
    // Get the sum of the array
    int sum = a[0];
    for (int i = 1; i < k; i++) {
  
        // If this condition is void at any stage
        // during filling up, then print -1
        if (a[i] > 2 * a[i - 1]) {
            cout << "-1";
            return;
        }
  
        // Else add it to the sum
        sum += a[i];
    }
  
    // If the sum condition is not
    // satisified, then print -1
    if (sum != n) {
        cout << "-1";
        return;
    }
  
    // Print the generated array
    for (int i = 0; i < k; i++)
        cout << a[i] << " ";
}
  
// Driver code
int main()
{
    int n = 26, k = 6;
    solve(n, k);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG {
  
    // Function that print the
    // desired array which
    // satisfies the given conditions
    static void solve(int n, int k)
    {
  
        int mini = 0;
        int x1 = 1;
        int[] a = new int[k];
        for (int i = 1; i <= k; i++) {
            mini += x1;
            a[i - 1] = x1;
            x1 += 1;
        }
  
        // If the lowest filling condition
        // is void, then it is not possible to
        // generate the required array
        if (n < mini) {
            System.out.print("-1");
            return;
        }
  
        int rem = n - mini;
        int cnt = rem / k;
        rem = rem % k;
  
        // Increase all the elements by cnt
        for (int i = 0; i < k; i++)
            a[i] += cnt;
  
        // Start filling from the back
        // till the number is a[i+1] <= 2*a[i]
        for (int i = k - 1; i > 0 && rem > 0; i--) {
  
            // Get the number to be filled
            int xx = a[i - 1] * 2;
            int left = xx - a[i];
  
            // If it is less than the
            // remaining numbers to be filled
            if (rem >= left) {
                a[i] = xx;
                rem -= left;
            }
  
            // less than remaining numbers
            // to be filled
            else {
                a[i] += rem;
                rem = 0;
            }
        }
  
        // Get the sum of the array
        int sum = a[0];
        for (int i = 1; i < k; i++) {
  
            // If this condition is void at any stage
            // during filling up, then print -1
            if (a[i] > 2 * a[i - 1]) {
                System.out.print("-1");
                return;
            }
  
            // Else add it to the sum
            sum += a[i];
        }
  
        // If the sum condition is not
        // satisified, then print -1
        if (sum != n) {
            System.out.print("-1");
            return;
        }
  
        // Print the generated array
        for (int i = 0; i < k; i++)
            System.out.print(a[i] + " ");
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int n = 26, k = 6;
        solve(n, k);
    }
}
  
// This code contributed by Rajput-Ji

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3 implementation of the approach
  
  
# Function that print the
# desired array which
# satisfies the given conditions
def solve(n, k):
    mini = 0
    x1 = 1
    a = [0 for i in range(k)]
    for i in range(1, k + 1):
        mini += x1
        a[i - 1] = x1
        x1 += 1
  
    # If the lowest filling condition
    # is void, then it is not possible to
    # generate the required array
    if (n < mini):
        print("-1",end = "")
        return
  
    rem = n - mini
    cnt = int(rem / k)
    rem = rem % k
  
    # Increase all the elements by cnt
    for i in range(k):
        a[i] += cnt
  
    # Start filling from the back
    # till the number is a[i+1] <= 2*a[i]
    i = k - 1
    while (i > 0 and rem > 0):
        # Get the number to be filled
        xx = a[i - 1] * 2
        left = xx - a[i]
        # If it is less than the
        # remaining numbers to be filled
        if (rem >= left):
            a[i] = xx
            rem -= left
  
        # less than remaining numbers
        # to be filled
        else:
            a[i] += rem
            rem = 0
              
        i -= 1
  
    # Get the sum of the array
    sum = a[0]
    for i in range(1, k):
        # If this condition is void at any stage
        # during filling up, then print -1
        if (a[i] > 2 * a[i - 1]):
            print("-1", end = "")
            return
  
        # Else add it to the sum
        sum += a[i]
  
    # If the sum condition is not
    # satisified, then print -1
    if (sum != n):
        print("-1", end = "")
        return
  
    # Print the generated array
    for i in range(k):
        print(a[i], end = " ")
  
# Driver code
if __name__ == '__main__':
    n = 26
    k = 6
    solve(n, k)
  
# This code is contributed by
# Surendra_Gangwar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
  
class GFG 
{
  
    // Function that print the
    // desired array which
    // satisfies the given conditions
    static void solve(int n, int k)
    {
  
        int mini = 0;
        int x1 = 1;
        int[] a = new int[k];
        for (int i = 1; i <= k; i++) 
        {
            mini += x1;
            a[i - 1] = x1;
            x1 += 1;
        }
  
        // If the lowest filling condition
        // is void, then it is not possible to
        // generate the required array
        if (n < mini) 
        {
            Console.Write("-1");
            return;
        }
  
        int rem = n - mini;
        int cnt = rem / k;
        rem = rem % k;
  
        // Increase all the elements by cnt
        for (int i = 0; i < k; i++)
            a[i] += cnt;
  
        // Start filling from the back
        // till the number is a[i+1] <= 2*a[i]
        for (int i = k - 1; i > 0 && rem > 0; i--) 
        {
  
            // Get the number to be filled
            int xx = a[i - 1] * 2;
            int left = xx - a[i];
  
            // If it is less than the
            // remaining numbers to be filled
            if (rem >= left) 
            {
                a[i] = xx;
                rem -= left;
            }
  
            // less than remaining numbers
            // to be filled
            else 
            {
                a[i] += rem;
                rem = 0;
            }
        }
  
        // Get the sum of the array
        int sum = a[0];
        for (int i = 1; i < k; i++)
        {
  
            // If this condition is void at any stage
            // during filling up, then print -1
            if (a[i] > 2 * a[i - 1])
            {
                Console.Write("-1");
                return;
            }
  
            // Else add it to the sum
            sum += a[i];
        }
  
        // If the sum condition is not
        // satisified, then print -1
        if (sum != n) {
            Console.Write("-1");
            return;
        }
  
        // Print the generated array
        for (int i = 0; i < k; i++)
            Console.Write(a[i] + " ");
    }
  
    // Driver code
    public static void Main()
    {
        int n = 26, k = 6;
        solve(n, k);
    }
}
  
// This code contributed by anuj_67..

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
// PHP implementation of the approach 
  
// Function that print the 
// desired array which 
// satisfies the given conditions 
function solve($n, $k
  
    $mini = 0; 
    $x1 = 1; 
    $a = array(); 
    for ($i = 1; $i <= $k; $i++) 
    
        $mini += $x1
        $a[$i - 1] = $x1
        $x1 += 1; 
    
  
    // If the lowest filling condition 
    // is void, then it is not possible to 
    // generate the required array 
    if ($n < $mini)
    
        echo "-1"
        return
    
  
    $rem = $n - $mini
    $cnt = floor($rem / $k); 
    $rem = $rem % $k
  
    // Increase all the elements by cnt 
    for ($i = 0; $i < $k; $i++) 
        $a[$i] += $cnt
  
    // Start filling from the back 
    // till the number is a[i+1] <= 2*a[i] 
    for ($i = $k - 1; $i > 0 && $rem > 0; $i--) 
    
          
        // Get the number to be filled 
        $xx = $a[$i - 1] * 2; 
        $left = $xx - $a[$i]; 
  
        // If it is less than the 
        // remaining numbers to be filled 
        if ($rem >= $left
        
            $a[$i] = $xx
            $rem -= $left
        
  
        // less than remaining numbers 
        // to be filled 
        else
        
            $a[$i] += $rem
            $rem = 0; 
        
    
  
    // Get the sum of the array 
    $sum = $a[0]; 
    for ($i = 1; $i < $k; $i++) 
    
  
        // If this condition is void at any stage 
        // during filling up, then print -1 
        if ($a[$i] > 2 * $a[$i - 1]) 
        
            echo "-1"
            return
        
  
        // Else add it to the sum 
        $sum += $a[$i]; 
    
  
    // If the sum condition is not 
    // satisified, then print -1 
    if ($sum != $n)
    
        echo "-1"
        return
    
  
    // Print the generated array 
    for ($i = 0; $i < $k; $i++) 
        echo $a[$i], " "
  
// Driver code 
$n = 26; $k = 6; 
solve($n, $k); 
  
// This code is contributed by AnkitRai01
?>

chevron_right


Output:

1 2 3 4 6 10


My Personal Notes arrow_drop_up

Striver(underscore)79 at Codechef and codeforces D

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.