📌  相关文章
📜  可以在每个步骤中使用加法或减法获得N的最小步骤

📅  最后修改于: 2021-04-24 04:09:08             🧑  作者: Mango

给定N,打印最少步数的序列,其中可以使用步数的加法或减法从0开始获得N。

注意:在每个步骤中,我们都可以从当前位置添加或减去等于步骤编号的数字。例如,在步骤1中,我们可以加1或-1。类似地,在步骤2中,我们加2或-2,依此类推。

下图显示了通过执行指定的操作可以从3开始从0到达的所有可能位置。

例子 :

Input: n = -4
Output: Minimum number of Steps: 3
        Step sequence: 1 -2 -3
Explanation: 
Step 1: At step 1 we add 1 to move from 0 to 1.
Step 2: At step 2 we add (-2) to move from 1 to -1.
Step 3: At step 3 we add (-3) to move from -1 to -4.

Input: n = 11
Output: Minimum number of steps = 4 
        Step sequence: 1 -2 3 4 5 

方法:解决上述问题的方法是在N分别为正数或负数的地方标记要减去或加的步数。如果N为正,则在每一步加数字,直到总和超过N。一旦总和超过N,请检查sum-N是否为偶数。如果sum-N为偶数,则在步骤号(sum-N)/ 2处进行减法。如果sum-N是一个奇数,则检查总和超过N的最后一步是偶数还是奇数。如果很奇怪,请再执行一个步骤,否则请执行两个步骤。如果在任何步骤中sum = N,那么在每个步骤中加法或减法都会给出答案。

令N = 11,则1 + 2 + 3 + 4 + 5 = 15超过11。减去15-11得到4,这等同于在步骤2进行减法。因此,步骤的顺序为1 -2 3 4 5

令N = 12,则1 + 2 + 3 + 4 + 5 = 15超过11。减去15-12得到3,这在任何步骤都不能执行。所以增加两个步骤,其一是6步骤和7步骤。目标是使和N为偶数,因此请在第6步执行加法,在第7步执行减法,合并后从和中减去1。现在sum-N是偶数,14-12 = 2,相当于在步骤1进行减法。因此,步骤序列为-1 2 3 4 5 6 -7

令N = 20,则1 + 2 + 3 + 4 + 5 + 6超过20。减去21-20得到1,因此将7加到21得到28。在下一步执行加法将为(sum-n)很奇怪sum-N等于8,相当于在步骤4进行减法。因此,步骤序列为1 2 3 -4 5 6 7。

下面是上述方法的说明:

C++
// C++ program to print the sequence
// of minimum steps in which N can be
// obtained from 0 using addition or
// subtraction of the step number.
#include 
using namespace std;
  
// Function to return the vector
// which stores the step sequence
vector findSteps(int n)
{
    // Steps sequence
    vector ans;
  
    // Current sum
    int sum = 0;
  
    // Sign of the number
    int sign = (n >= 0 ? 1 : -1);
    n = abs(n);
  
    int i;
    // Basic steps required to get sum >= required value.
    for (i = 1; sum < n; i++) {
        ans.push_back(sign * i);
        sum += i;
    }
    cout << i << endl;
  
    // Reached ahead of N
    if (sum > sign * n) {
  
        // If the last step was an odd number
        if (i % 2) {
            sum -= n;
  
            // sum-n is odd
            if (sum % 2) {
                ans.push_back(sign * i);
                sum += i++;
            }
            // subtract the equivalent sum-n
            ans[(sum / 2) - 1] *= -1;
        }
        else {
            sum -= n;
  
            // sum-n is odd
            if (sum % 2) {
  
                // since addition of next step and subtraction
                // at the next next step will give sum = sum-1
                sum--;
                ans.push_back(sign * i);
                ans.push_back(sign * -1 * (i + 1));
            }
            // subtract the equivalent sum-n
            ans[(sum / 2) - 1] *= -1;
        }
    }
    // returns the vector
    return ans;
}
  
// Function to print the steps
void printSteps(int n)
{
    vector v = findSteps(n);
  
    // prints the number of steps which is the size of vector
    cout << "Minimum number of Steps: " << v.size() << "\n";
  
    cout << "Step sequence:";
  
    // prints the steps stored
    // in the vector
    for (int i = 0; i < v.size(); i++)
        cout << v[i] << " ";
}
  
// Driver Code
int main()
{
    int n = 20;
    printSteps(n);
    return 0;
}


Java
// Java program to print the 
// sequence of minimum steps 
// in which N can be obtained 
// from 0 using addition or 
// subtraction of the step 
// number.
import java.util.*;
  
class GFG
{
  
// Function to return the
// Arraylist which stores 
// the step sequence
static ArrayList findSteps(int n)
{
    // Steps sequence
    ArrayList ans = new ArrayList();
  
    // Current sum
    int sum = 0;
  
    // Sign of the number
    int sign = (n >= 0 ? 1 : -1);
    n = Math.abs(n);
  
    int i;
    // Basic steps required to
    // get sum >= required value.
    for (i = 1; sum < n; i++) 
    {
        ans.add(sign * i);
        sum += i;
    }
    System.out.println( i );
  
    // Reached ahead of N
    if (sum > sign * n) 
    {
  
        // If the last step 
        // was an odd number
        if (i % 2 != 0) 
        {
            sum -= n;
  
            // sum-n is odd
            if (sum % 2 != 0) 
            {
                ans.add(sign * i);
                sum += i++;
            }
              
            // subtract the 
            // equivalent sum-n
            ans.set((sum / 2) - 1, 
            ans.get((sum / 2) - 1) * -1);
        }
        else 
        {
            sum -= n;
  
            // sum-n is odd
            if (sum % 2 != 0) 
            {
  
                // since addition of next 
                // step and subtraction at
                // the next next step will
                // give sum = sum-1
                sum--;
                ans.add(sign * i);
                ans.add(sign * -1 * (i + 1));
            }
              
            // subtract the 
            // equivalent sum-n
            ans.set((sum / 2) - 1,
            ans.get((sum / 2) - 1) * -1);
        }
    }
      
    // returns the Arraylist
    return ans;
}
  
// Function to print the steps
static void printSteps(int n)
{
    ArrayList v = findSteps(n);
  
    // prints the number of steps 
    // which is the size of Arraylist
    System.out.println("Minimum number " + 
                            "of Steps: " + 
                                v.size());
  
    System.out.print("Step sequence:");
  
    // prints the steps stored
    // in the Arraylist
    for (int i = 0; i < v.size(); i++)
        System.out.print(v.get(i) + " ");
}
  
// Driver Code
public static void main(String args[])
{
    int n = 20;
    printSteps(n);
}
}
// This code is contributed
// by Arnab Kundu


C#
// C# program to print the 
// sequence of minimum steps 
// in which N can be obtained 
// from 0 using addition or 
// subtraction of the step 
// number.
using System;
using System.Collections.Generic;
  
class GFG
{
  
// Function to return the
// Arraylist which stores 
// the step sequence
static List findSteps(int n)
{
    // Steps sequence
    List ans = new List();
  
    // Current sum
    int sum = 0;
  
    // Sign of the number
    int sign = (n >= 0 ? 1 : -1);
    n = Math.Abs(n);
  
    int i;
      
    // Basic steps required to
    // get sum >= required value.
    for (i = 1; sum < n; i++) 
    {
        ans.Add(sign * i);
        sum += i;
    }
    Console.WriteLine( i );
  
    // Reached ahead of N
    if (sum > sign * n) 
    {
  
        // If the last step 
        // was an odd number
        if (i % 2 != 0) 
        {
            sum -= n;
  
            // sum-n is odd
            if (sum % 2 != 0) 
            {
                ans.Add(sign * i);
                sum += i++;
            }
              
            // subtract the 
            // equivalent sum-n
            ans[(sum / 2) - 1]= 
            ans[(sum / 2) - 1] * -1;
        }
        else
        {
            sum -= n;
  
            // sum-n is odd
            if (sum % 2 != 0) 
            {
  
                // since addition of next 
                // step and subtraction at
                // the next next step will
                // give sum = sum-1
                sum--;
                ans.Add(sign * i);
                ans.Add(sign * -1 * (i + 1));
            }
              
            // subtract the 
            // equivalent sum-n
            ans[(sum / 2) - 1]=
            ans[(sum / 2) - 1] * -1;
        }
    }
      
    // returns the Arraylist
    return ans;
}
  
// Function to print the steps
static void printSteps(int n)
{
    List v = findSteps(n);
  
    // prints the number of steps 
    // which is the size of Arraylist
    Console.WriteLine("Minimum number " + 
                            "of Steps: " + 
                                v.Count);
  
    Console.Write("Step sequence:");
  
    // prints the steps stored
    // in the Arraylist
    for (int i = 0; i < v.Count; i++)
        Console.Write(v[i] + " ");
}
  
// Driver Code
public static void Main(String []args)
{
    int n = 20;
    printSteps(n);
}
}
  
// This code is contributed by Rajput-Ji


输出 :
7
Minimum number of Steps: 7
Step sequence:1 2 3 -4 5 6 7

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

注意: sum = i *(i + 1)/ 2等于或大于N,这使i为sqrt(N)。