给定两个整数N和K ,任务是生成长度为K的数组arr [] ,使得:
- arr [0] + arr [1] +…+ arr [K – 1] = N。
- 当0≤i
arr [i]> 0 。 - arr [i]
for 0≤i 。
如果有多个答案,请找到其中一个,否则,打印-1 。
例子:
Input: N = 26, K = 6
Output: 1 2 4 5 6 8
The generated array satisfies all of the given conditions.
Input: N = 8, K = 3
Output: -1
方法:令r = n – k *(k + 1)/ 2 。如果r <0,则答案已经为-1 。否则,我们构造一个数组arr [] ,其中所有arr [i]都是floor(r / k),除了最右边的r%k值,它们都是ceil(r / k) 。
不难看出,此数组的总和为r ,它以不降序排列,并且最大元素和最小元素之间的差不大于1。
让我们添加1 arr中[1],2 arr中[2]等(这是我们在与n减去
开始)。
然后,如果r!= k – 1或k = 1,则arr []是我们所需的数组。否则,我们得到了一些类型为1,3,…..,arr [k]的数组。对于k = 2或k = 3 ,这种情况没有答案。否则,我们可以从arr [2]中减去1并将其加到arr [k]中,此答案将是正确的。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to generate and print
// the required array
void generateArray(int n, int k)
{
// Initializing the array
vector array(k, 0);
// Finding r (from above approach)
int remaining = n - int(k * (k + 1) / 2);
// If r<0
if (remaining < 0)
cout << ("NO");
int right_most = remaining % k;
// Finding ceiling and floor values
int high = ceil(remaining / (k * 1.0));
int low = floor(remaining / (k * 1.0));
// Fill the array with ceiling values
for (int i = k - right_most; i < k; i++)
array[i]= high;
// Fill the array with floor values
for (int i = 0; i < (k - right_most); i++)
array[i]= low;
// Add 1, 2, 3, ... with corresponding values
for (int i = 0; i < k; i++)
array[i] += i + 1;
if (k - 1 != remaining or k == 1)
{
for(int u:array) cout << u << " ";
}
// There is no solution for below cases
else if (k == 2 or k == 3)
printf("-1\n");
else
{
// Modify A[1] and A[k-1] to get
// the required array
array[1] -= 1;
array[k - 1] += 1;
for(int u:array) cout << u << " ";
}
}
// Driver Code
int main()
{
int n = 26, k = 6;
generateArray(n, k);
return 0;
}
// This code is contributed
// by Mohit Kumar
Java
// Java implementation of the approach
class GFG
{
// Function to generate and print
// the required array
static void generateArray(int n, int k)
{
// Initializing the array
int []array = new int[k];
// Finding r (from above approach)
int remaining = n - (k * (k + 1) / 2);
// If r < 0
if (remaining < 0)
System.out.print("NO");
int right_most = remaining % k;
// Finding ceiling and floor values
int high = (int) Math.ceil(remaining / (k * 1.0));
int low = (int) Math.floor(remaining / (k * 1.0));
// Fill the array with ceiling values
for (int i = k - right_most; i < k; i++)
array[i] = high;
// Fill the array with floor values
for (int i = 0; i < (k - right_most); i++)
array[i] = low;
// Add 1, 2, 3, ... with corresponding values
for (int i = 0; i < k; i++)
array[i] += i + 1;
if (k - 1 != remaining || k == 1)
{
for(int u:array)
System.out.print(u + " ");
}
// There is no solution for below cases
else if (k == 2 || k == 3)
System.out.printf("-1\n");
else
{
// Modify A[1] and A[k-1] to get
// the required array
array[1] -= 1;
array[k - 1] += 1;
for(int u:array)
System.out.print(u + " ");
}
}
// Driver Code
public static void main(String[] args)
{
int n = 26, k = 6;
generateArray(n, k);
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 implementation of the approach
import sys
from math import floor, ceil
# Function to generate and print
# the required array
def generateArray(n, k):
# Initializing the array
array = [0] * k
# Finding r (from above approach)
remaining = n-int(k*(k + 1)/2)
# If r<0
if remaining<0:
print("NO")
sys.exit()
right_most = remaining % k
# Finding ceiling and floor values
high = ceil(remaining / k)
low = floor(remaining / k)
# Fill the array with ceiling values
for i in range(k-right_most, k):
array[i]= high
# Fill the array with floor values
for i in range(k-right_most):
array[i]= low
# Add 1, 2, 3, ... with corresponding values
for i in range(k):
array[i]+= i + 1
if k-1 != remaining or k == 1:
print(*array)
sys.exit()
# There is no solution for below cases
elif k == 2 or k == 3:
print("-1")
sys.exit()
else:
# Modify A[1] and A[k-1] to get
# the required array
array[1]-= 1
array[k-1]+= 1
print(*array)
sys.exit()
# Driver Code
if __name__=="__main__":
n, k = 26, 6
generateArray(n, k)
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to generate and print
// the required array
static void generateArray(int n, int k)
{
// Initializing the array
int []array = new int[k];
// Finding r (from above approach)
int remaining = n - (k * (k + 1) / 2);
// If r < 0
if (remaining < 0)
Console.Write("NO");
int right_most = remaining % k;
// Finding ceiling and floor values
int high = (int) Math.Ceiling(remaining /
(k * 1.0));
int low = (int) Math.Floor(remaining /
(k * 1.0));
// Fill the array with ceiling values
for (int i = k - right_most; i < k; i++)
array[i] = high;
// Fill the array with floor values
for (int i = 0;
i < (k - right_most); i++)
array[i] = low;
// Add 1, 2, 3, ... with
// corresponding values
for (int i = 0; i < k; i++)
array[i] += i + 1;
if (k - 1 != remaining || k == 1)
{
foreach(int u in array)
Console.Write(u + " ");
}
// There is no solution for below cases
else if (k == 2 || k == 3)
Console.Write("-1\n");
else
{
// Modify A[1] and A[k-1] to get
// the required array
array[1] -= 1;
array[k - 1] += 1;
foreach(int u in array)
Console.Write(u + " ");
}
}
// Driver Code
public static void Main(String[] args)
{
int n = 26, k = 6;
generateArray(n, k);
}
}
// This code is contributed by PrinciRaj1992
输出:
1 2 4 5 6 8