📌  相关文章
📜  找出 K 个不超过 N 且总和为 S 的正整数

📅  最后修改于: 2021-10-25 06:48:13             🧑  作者: Mango

给定三个正整数S、KN ,任务是找到K 个不同的正整数,不超过N且总和等于S。如果不可能找到K 个这样的正整数,则打印-1

例子:

处理方法:按照以下步骤解决问题:

  • 如果N小于K ,则打印-1
  • 如果S小于前K 个自然数的总和,即 (1 + 2 + … + K) 或者如果S大于最后K 个自然数的总和,即从NN – K + 1 ,则打印– 1 .
  • 1迭代并继续添加变量中遇到的每个自然数,例如s1 ,而s1 ≤ S。将所有遇到的元素插入数组中,例如nums[]
  • nums[] 中提取K – 1 个元素并存储在另一个数组中,比如answer
  • 数组answer[]中的第K元素将是(s1 – s2) ,其中s2是数组answer[] 中存在的K – 1 个元素的总和。
  • 反向遍历数组answer[]并将所有数组元素减少到小于或等于N

下面是上述方法的实现:

C++
// C++ implementation
// for the above approach
 
#include 
using namespace std;
 
// Function to represent S as
// the sum of K positive integers
// less than or equal to N
void solve(int S, int K, int N)
{
    if (K > N) {
        cout << "-1" << endl;
        return;
    }
 
    int max_sum = 0, min_sum = 0;
 
    for (int i = 1; i <= K; i++) {
        min_sum += i;
        max_sum += N - i + 1;
    }
 
    // If S can cannot be represented
    // as sum of K integers
    if (S < min_sum || S > max_sum) {
        cout << "-1" << endl;
        return;
    }
 
    int s1 = 0;
 
    vector nums;
 
    for (int i = 1; i <= N; i++) {
 
        // If sum of first i natural
        // numbers exceeds S
        if (s1 > S)
            break;
 
        s1 += i;
 
        // Insert i into nums[]
        nums.push_back(i);
    }
 
    vector answer;
    int s2 = 0;
 
    // Insert first K - 1 positive
    // numbers into answer[]
    for (int i = 0; i < K - 1; i++) {
        answer.push_back(nums[i]);
        s2 += nums[i];
    }
 
    // Insert the K-th number
    answer.push_back(S - s2);
 
    int Max = N;
 
    // Traverse the array answer[]
    for (int i = answer.size() - 1; i >= 0; i--) {
 
        // If current element exceeds N
        if (answer[i] > Max) {
 
            int extra = answer[i] - Max;
 
            // Add the extra value to
            // the previous element
            if (i - 1 >= 0)
                answer[i - 1] += extra;
 
            // Reduce current element to N
            answer[i] = Max;
 
            Max--;
        }
 
        else
            break;
    }
 
    // Printing the K numbers
    for (auto x : answer)
        cout << x << " ";
 
    cout << endl;
}
 
// Driver Code
int main()
{
    int S = 15, K = 4, N = 8;
    solve(S, K, N);
 
    return 0;
}


Java
// Java implementation
// for the above approach
import java.util.Vector;
 
class GFG{
 
// Function to represent S as
// the sum of K positive integers
// less than or equal to N
static void solve(int S, int K, int N)
{
    if (K > N)
    {
        System.out.println("-1");
        return;
    }
 
    int max_sum = 0, min_sum = 0;
 
    for(int i = 1; i <= K; i++)
    {
        min_sum += i;
        max_sum += N - i + 1;
    }
 
    // If S can cannot be represented
    // as sum of K integers
    if (S < min_sum || S > max_sum)
    {
        System.out.println("-1");
        return;
    }
 
    int s1 = 0;
 
    Vector nums = new Vector<>();
 
    for(int i = 1; i <= N; i++)
    {
         
        // If sum of first i natural
        // numbers exceeds S
        if (s1 > S)
            break;
 
        s1 += i;
 
        // Insert i into nums[]
        nums.add(i);
    }
    Vector answer = new Vector<>();
    int s2 = 0;
 
    // Insert first K - 1 positive
    // numbers into answer[]
    for(int i = 0; i < K - 1; i++)
    {
        answer.add(nums.get(i));
        s2 += nums.get(i);
    }
 
    // Insert the K-th number
    answer.add(S - s2);
 
    int Max = N;
 
    // Traverse the array answer[]
    for(int i = answer.size() - 1;
            i >= 0; i--)
    {
         
        // If current element exceeds N
        if (answer.get(i) > Max)
        {
            int extra = answer.get(i) - Max;
 
            // Add the extra value to
            // the previous element
            if (i - 1 >= 0)
                answer.set(i - 1,
                answer.get(i - 1) + extra);
 
            // Reduce current element to N
            answer.set(i, Max);
 
            Max--;
        }
        else
            break;
    }
 
    // Printing the K numbers
    for(int x : answer)
        System.out.print(x + " ");
 
    System.out.println();
}
 
// Driver code
public static void main(String[] args)
{
    int S = 15, K = 4, N = 8;
     
    solve(S, K, N);
}
}
 
// This code is contributed by abhinavjain194


Python3
# Python3 implementation
# for the above approach
 
# Function to represent S as
# the sum of K positive integers
# less than or equal to N
def solve(S, K, N):
    if (K > N):
        print("-1")
        return
 
    max_sum, min_sum = 0, 0
 
    for i in range(K + 1):
        min_sum += i
        max_sum += N - i + 1
 
    # If S can cannot be represented
    # as sum of K integers
    if (S < min_sum or S > max_sum):
        print("-1")
        return
 
    s1 = 0
 
    nums = []
 
    for i in range(1, N + 1):
 
        # If sum of first i natural
        # numbers exceeds S
        if (s1 > S):
            break
 
        s1 += i
 
        # Insert i into nums[]
        nums.append(i)
 
    answer = []
    s2 = 0
 
    # Insert first K - 1 positive
    # numbers into answer[]
    for i in range(K - 1):
        answer.append(nums[i])
        s2 += nums[i]
 
    # Insert the K-th number
    answer.append(S - s2)
 
    Max = N
 
    # Traverse the array answer[]
    for i in range(len(answer)-1,-1,-1):
 
        # If current element exceeds N
        if (answer[i] > Max):
 
            extra = answer[i] - Max
 
            # Add the extra value to
            # the previous element
            if (i - 1 >= 0):
                answer[i - 1] += extra
 
            # Reduce current element to N
            answer[i] = Max
 
            Max -= 1
        else:
            break
 
    # Printing the K numbers
    for x in answer:
        print(x, end = " ")
 
 
# Driver Code
if __name__ == '__main__':
    S,K,N = 15, 4, 8
    solve(S, K, N)
 
# This code is contributed by mohit kumar 29.


C#
// C# implementation
// for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
     
// Function to represent S as
// the sum of K positive integers
// less than or equal to N
static void solve(int S, int K, int N)
{
    if (K > N)
    {
        Console.WriteLine("-1");
        return;
    }
 
    int max_sum = 0, min_sum = 0;
 
    for(int i = 1; i <= K; i++)
    {
        min_sum += i;
        max_sum += N - i + 1;
    }
 
    // If S can cannot be represented
    // as sum of K integers
    if (S < min_sum || S > max_sum)
    {
        Console.WriteLine("-1");
        return;
    }
 
    int s1 = 0;
    List nums = new List();
 
    for(int i = 1; i <= N; i++)
    {
         
        // If sum of first i natural
        // numbers exceeds S
        if (s1 > S)
            break;
 
        s1 += i;
 
        // Insert i into nums[]
        nums.Add(i);
    }
 
    List answer = new List();
    int s2 = 0;
 
    // Insert first K - 1 positive
    // numbers into answer[]
    for(int i = 0; i < K - 1; i++)
    {
        answer.Add(nums[i]);
        s2 += nums[i];
    }
 
    // Insert the K-th number
    answer.Add(S - s2);
 
    int Max = N;
 
    // Traverse the array answer[]
    for(int i = answer.Count - 1; i >= 0; i--)
    {
         
        // If current element exceeds N
        if (answer[i] > Max)
        {
            int extra = answer[i] - Max;
 
            // Add the extra value to
            // the previous element
            if (i - 1 >= 0)
                answer[i - 1] += extra;
 
            // Reduce current element to N
            answer[i] = Max;
 
            Max--;
        }
        else
            break;
    }
 
    // Printing the K numbers
    foreach(int x in answer)
        Console.Write(x + " ");
 
    Console.WriteLine();
}
 
// Driver Code
public static void Main()
{
    int S = 15, K = 4, N = 8;
    solve(S, K, N);
}
}
 
// This code is contributed by ukasp


Javascript


输出:
1 2 4 8

时间复杂度: O(N)
辅助空间: O(N)