📌  相关文章
📜  生成一个由K个元素组成的数组,使得元素之和为N,并且满足条件a [i] <a [i + 1] <= 2 * a [i] |套装2

📅  最后修改于: 2021-04-22 03:24:21             🧑  作者: Mango

给定两个整数NK ,任务是生成长度为K的数组arr [] ,使得:

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

如果有多个答案,请找到其中一个,否则,打印-1
例子:

方法:最初,我们以最低的配置形成阵列,将满足给定条件的1,2,3,4 ..填充到阵列中。如果1..K的总和大于N,则无法形成数组。为了形成数组,首先用1、2、3,.. K填充数组。再次将( n-sum)/ k添加到数组中的每个元素,因为这样相加时,没有条件是无效的,因为我们在每个数字上添加相等的元素。
剩余的数字rem从后面贪婪地相加,使每个数字成为其先前数字的两倍。填满数组后,如果不满足任何给定条件,则打印-1,否则形成的数组将是我们想要的答案。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
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;
}


Java
// 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


Python3
# 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


C#
// 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..


PHP
 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
?>


输出:
1 2 3 4 6 10

时间复杂度: O(K)

辅助空间: O(K)