📜  最小化给定多项式的根的总和

📅  最后修改于: 2021-04-27 19:26:28             🧑  作者: Mango

给定一个数组,其元素表示次数为n的多项式的系数,如果多项式的次数为n,则该数组将具有n + 1个元素(对于多项式的常数另加1个元素)。交换数组的某些元素并打印结果数组,以使给定多项式的根的总和尽可能小,而与根的性质无关。
请注意:除了数组元素的第一个元素也可以为0之外,多项式的次数始终大于1。

例子:

Input : -4 1 6 -3 -2 -1
Output : 1 6 -4 -3 -2 -1
        Here, the array is -4, 1, 6, -3, -2, -1
        i.e the polynomial is -4.x^5 + 1.x^4 + 6.x^3 - 3.x^2 - 2.x^1 - 1
        minimum sum = -6 

Input : -9 0 9
Output :-9 0 9
       Here polynomial is 
       -9.x^2 + 0.x^1 + 9
       minimum sum = 0

解决方案:让我们回想一下,如果多项式p(x)= ax ^ n + bx ^ n-1 + cx ^ n-2 +…+ k,那么多项式根的总和就等于多项式由-b / a给出。有关详细信息,请参见Vieta的公式。
我们必须最小化-b / a,即最大化b / a,即最大化b并最小化a。因此,如果能够以某种方式最大化b并将a最小化,我们将交换系数的值,并照原样复制数组的其余部分。

C++
// C++ program to find minimum sum of roots of a
// given polynomial
#include 
using namespace std;
 
void getMinimumSum(int arr[], int n)
{
    // resultant vector
    vector res;
 
    // a vector that store indices of the positive
    // elements
    vector pos;
 
    // a vector that store indices of the negative
    // elements
    vector neg;
 
    for (int i = 0; i < n; i++) {
        if (arr[i] > 0)
            pos.push_back(i);       
        else if (arr[i] < 0)
            neg.push_back(i);       
    }
 
    // Case - 1:
    if (pos.size() >= 2 && neg.size() >= 2) {
        int posMax = INT_MIN, posMaxIdx = -1;
        int posMin = INT_MAX, posMinIdx = -1;
 
        int negMax = INT_MIN, negMaxIdx = -1;
        int negMin = INT_MAX, negMinIdx = -1;
 
        for (int i = 0; i < pos.size(); i++) {
            if (arr[pos[i]] > posMax) {
                posMaxIdx = pos[i];
                posMax = arr[posMaxIdx];
            }
        }
 
        for (int i = 0; i < pos.size(); i++) {
            if (arr[pos[i]] < posMin &&
                pos[i] != posMaxIdx) {
                posMinIdx = pos[i];
                posMin = arr[posMinIdx];
            }
        }
 
        for (int i = 0; i < neg.size(); i++) {
            if (abs(arr[neg[i]]) > negMax) {
                negMaxIdx = neg[i];
                negMax = abs(arr[negMaxIdx]);
            }
        }
 
        for (int i = 0; i < neg.size(); i++) {
            if (abs(arr[neg[i]]) < negMin &&
                neg[i] != negMaxIdx) {
                negMinIdx = neg[i];
                negMin = abs(arr[negMinIdx]);
            }
        }
 
        double posVal = -1.0 * (double)posMax / (double)posMin;
        double negVal = -1.0 * (double)negMax / (double)negMin;
 
        if (posVal < negVal) {
            res.push_back(arr[posMinIdx]);
            res.push_back(arr[posMaxIdx]);
 
            for (int i = 0; i < n; i++) {
                if (i != posMinIdx && i != posMaxIdx) {
                    res.push_back(arr[i]);
                }
            }
        }
        else {
            res.push_back(arr[negMinIdx]);
            res.push_back(arr[negMaxIdx]);
 
            for (int i = 0; i < n; i++) {
                if (i != negMinIdx && i != negMaxIdx) {
                    res.push_back(arr[i]);
                }
            }
        }
        for (int i = 0; i < res.size(); i++) {
            cout << res[i] << " ";
        }
        cout << "\n";
    }
 
    // Case - 2:
    else if (pos.size() >= 2) {
        int posMax = INT_MIN, posMaxIdx = -1;
        int posMin = INT_MAX, posMinIdx = -1;
 
        for (int i = 0; i < pos.size(); i++) {
            if (arr[pos[i]] > posMax) {
                posMaxIdx = pos[i];
                posMax = arr[posMaxIdx];
            }
        }
 
        for (int i = 0; i < pos.size(); i++) {
            if (arr[pos[i]] < posMin &&
                pos[i] != posMaxIdx) {
                posMinIdx = pos[i];
                posMin = arr[posMinIdx];
            }
        }
 
        res.push_back(arr[posMinIdx]);
        res.push_back(arr[posMaxIdx]);
 
        for (int i = 0; i < n; i++) {
            if (i != posMinIdx && i != posMaxIdx) {
                res.push_back(arr[i]);
            }
        }
        for (int i = 0; i < res.size(); i++) {
            cout << res[i] << " ";
        }
        cout << "\n";
    }
 
    // Case - 3:
    else if (neg.size() >= 2) {
        int negMax = INT_MIN, negMaxIdx = -1;
        int negMin = INT_MAX, negMinIdx = -1;
 
        for (int i = 0; i < neg.size(); i++) {
            if (abs(arr[neg[i]]) > negMax) {
                negMaxIdx = neg[i];
                negMax = abs(arr[negMaxIdx]);
            }
        }
 
        for (int i = 0; i < neg.size(); i++) {
            if (abs(arr[neg[i]]) < negMin &&
                neg[i] != negMaxIdx) {
                negMinIdx = neg[i];
                negMin = abs(arr[negMinIdx]);
            }
        }
 
        res.push_back(arr[negMinIdx]);
        res.push_back(arr[negMaxIdx]);
 
        for (int i = 0; i < n; i++)
            if (i != negMinIdx && i != negMaxIdx)
                res.push_back(arr[i]);
 
        for (int i = 0; i < res.size(); i++)
            cout << res[i] << " ";
         
        cout << "\n";
    }
 
    // Case - 4:
    else {
        cout << "No swap required\n";
    }
}
 
int main()
{
    int arr[] = { -4, 1, 6, -3, -2, -1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    getMinimumSum(arr, n);
    return 0;
}


Java
// Java  program to find minimum sum of roots of a
// given polynomial
import java.io.*;
import java.util.*;
 
class GFG
{   
  static void getMinimumSum(int arr[], int n)
  {
 
    // resultant vector
    ArrayList res = new ArrayList();
 
    // a vector that store indices of the positive
    // elements
    ArrayList pos = new ArrayList();
 
    // a vector that store indices of the negative
    // elements
    ArrayList neg = new ArrayList();
 
    for (int i = 0; i < n; i++)
    {
      if (arr[i] > 0)
        pos.add(i);       
      else if (arr[i] < 0)
        neg.add(i);       
    }
 
    // Case - 1:
    if (pos.size() >= 2 && neg.size() >= 2) {
      int posMax = Integer.MIN_VALUE, posMaxIdx = -1;
      int posMin = Integer.MAX_VALUE, posMinIdx = -1;
 
      int negMax = Integer.MIN_VALUE, negMaxIdx = -1;
      int negMin = Integer.MAX_VALUE, negMinIdx = -1;
 
      for (int i = 0; i < pos.size(); i++) {
        if (arr[pos.get(i)] > posMax) {
          posMaxIdx = pos.get(i);
          posMax = arr[posMaxIdx];
        }
      }
 
      for (int i = 0; i < pos.size(); i++) {
        if (arr[pos.get(i)] < posMin &&
            pos.get(i) != posMaxIdx) {
          posMinIdx = pos.get(i);
          posMin = arr[posMinIdx];
        }
      }
 
      for (int i = 0; i < neg.size(); i++) {
        if (Math.abs(arr[neg.get(i)]) > negMax) {
          negMaxIdx = neg.get(i);
          negMax = Math.abs(arr[negMaxIdx]);
        }
      }
 
      for (int i = 0; i < neg.size(); i++) {
        if (Math.abs(arr[neg.get(i)]) < negMin &&
            neg.get(i) != negMaxIdx) {
          negMinIdx = neg.get(i);
          negMin = Math.abs(arr[negMinIdx]);
        }
      }
 
      double posVal = -1.0 * (double)posMax / (double)posMin;
      double negVal = -1.0 * (double)negMax / (double)negMin;
 
      if (posVal < negVal) {
        res.add(arr[posMinIdx]);
        res.add(arr[posMaxIdx]);
 
        for (int i = 0; i < n; i++) {
          if (i != posMinIdx && i != posMaxIdx) {
            res.add(arr[i]);
          }
        }
      }
      else {
        res.add(arr[negMinIdx]);
        res.add(arr[negMaxIdx]);
 
        for (int i = 0; i < n; i++) {
          if (i != negMinIdx && i != negMaxIdx) {
            res.add(arr[i]);
          }
        }
      }
      for (int i = 0; i < res.size(); i++) {
        System.out.print(res.get(i) + " ");
 
      }
      System.out.println();
 
    }
 
    // Case - 2:
    else if (pos.size() >= 2) {
      int posMax = Integer.MIN_VALUE, posMaxIdx = -1;
      int posMin = Integer.MAX_VALUE, posMinIdx = -1;
 
      for (int i = 0; i < pos.size(); i++) {
        if (arr[pos.get(i)] > posMax) {
          posMaxIdx = pos.get(i);
          posMax = arr[posMaxIdx];
        }
      }
 
      for (int i = 0; i < pos.size(); i++) {
        if (arr[pos.get(i)] < posMin &&
            pos.get(i) != posMaxIdx) {
          posMinIdx = pos.get(i);
          posMin = arr[posMinIdx];
        }
      }
 
      res.add(arr[posMinIdx]);
      res.add(arr[posMaxIdx]);
 
      for (int i = 0; i < n; i++) {
        if (i != posMinIdx && i != posMaxIdx) {
          res.add(arr[i]);
        }
      }
      for (int i = 0; i < res.size(); i++) {
        System.out.print(res.get(i)+" ");
 
      }
      System.out.println();
 
    }
 
    // Case - 3:
    else if (neg.size() >= 2) {
      int negMax = Integer.MIN_VALUE, negMaxIdx = -1;
      int negMin = Integer.MAX_VALUE, negMinIdx = -1;
 
      for (int i = 0; i < neg.size(); i++) {
        if (Math.abs(arr[neg.get(i)]) > negMax) {
          negMaxIdx = neg.get(i);
          negMax = Math.abs(arr[negMaxIdx]);
        }
      }
 
      for (int i = 0; i < neg.size(); i++) {
        if (Math.abs(arr[neg.get(i)]) < negMin &&
            neg.get(i) != negMaxIdx) {
          negMinIdx = neg.get(i);
          negMin = Math.abs(arr[negMinIdx]);
        }
      }
 
      res.add(arr[negMinIdx]);
      res.add(arr[negMaxIdx]);
 
      for (int i = 0; i < n; i++)
        if (i != negMinIdx && i != negMaxIdx)
          res.add(arr[i]);
 
      for (int i = 0; i < res.size(); i++)
        System.out.println(res.get(i)+" ");
 
      System.out.println();
 
    }
 
    // Case - 4:
    else {
      System.out.println("No swap required");
 
    }
  }
 
  // Driver code
  public static void main (String[] args)
  {
    int arr[] = { -4, 1, 6, -3, -2, -1 };
    int n = arr.length;
    getMinimumSum(arr, n);
  }
}
 
// This code is contributed by rag2127


Python3
# Python3 program to find
# minimum sum of roots of a
# given polynomial
import sys
 
def getMinimumSum(arr, n):
 
    # resultant list
    res = []
 
    # a lis that store indices
    # of the positive
    # elements
    pos = []
 
    # a list that store indices
    # of the negative
    # elements
    neg = []
 
    for i in range(n):
        if (arr[i] > 0):
            pos.append(i)
        elif (arr[i] < 0):
            neg.append(i)
 
    # Case - 1:
    if (len(pos) >= 2 and
        len(neg) >= 2):
        posMax = -sys.maxsize-1
        posMaxIdx = -1
        posMin = sys.maxsize
        posMinIdx = -1
        negMax = -sys.maxsize-1
        negMaxIdx = -1
        negMin = sys.maxsize
        negMinIdx = -1
 
        for i in range(len(pos)):
            if (arr[pos[i]] > posMax):
                posMaxIdx = pos[i]
                posMax = arr[posMaxIdx]
 
        for i in range(len(pos)):
            if (arr[pos[i]] < posMin and
                    pos[i] != posMaxIdx):
                posMinIdx = pos[i]
                posMin = arr[posMinIdx]
 
        for i in range(len(neg)):
            if (abs(arr[neg[i]]) > negMax):
                negMaxIdx = neg[i]
                negMax = abs(arr[negMaxIdx])
 
        for i in range(len(neg)):
            if (abs(arr[neg[i]]) < negMin and
                    neg[i] != negMaxIdx):
                negMinIdx = neg[i]
                negMin = abs(arr[negMinIdx])
 
        posVal = (-1.0 * posMax /
                         posMin)
        negVal = (-1.0 * negMax /
                         negMin)
 
        if (posVal < negVal):
            res.append(arr[posMinIdx])
            res.append(arr[posMaxIdx])
 
            for i in range(n):
                if (i != posMinIdx and
                    i != posMaxIdx):
                    res.append(arr[i])
        else:
            res.append(arr[negMinIdx])
            res.append(arr[negMaxIdx])
 
            for i in range(n):
                if (i != negMinIdx and
                    i != negMaxIdx):
                    resal.apend(arr[i])
 
        for i in range(len(res)):
            print(res[i], end = " ")
 
        print()
 
    # Case - 2:
    elif (len(pos) >= 2):
        posMax = -sys.maxsize
        posMaxIdx = -1
        posMin = sys.maxsize
        posMinIdx = -1
 
        for i in range(len(pos)):
            if (arr[pos[i]] > posMax):
                posMaxIdx = pos[i]
                posMax = arr[posMaxIdx]
 
        for i in range(len(pos)):
            if (arr[pos[i]] < posMin and
                    pos[i] != posMaxIdx):
                posMinIdx = pos[i]
                posMin = arr[posMinIdx]
 
        res.append(arr[posMinIdx])
        res.append(arr[posMaxIdx])
 
        for i in range(n):
            if (i != posMinIdx and
                i != posMaxIdx):
                res.append(arr[i])
 
        for i in range(len(res)):
            print(res[i], end = " ")
 
        print()
 
    # Case - 3:
    elif (len(neg) >= 2):
        negMax = -sys.maxsize
        negMaxIdx = -1
        negMin = sys.maxsize
        negMinIdx = -1
 
        for i in range(len(neg)):
            if (abs(arr[neg[i]]) > negMax):
                negMaxIdx = neg[i]
                negMax = abs(arr[negMaxIdx])
 
        for i in range(len(neg)):
            if (abs(arr[neg[i]]) < negMin and
                    neg[i] != negMaxIdx):
                negMinIdx = neg[i]
                negMin = abs(arr[negMinIdx])
 
        res.append(arr[negMinIdx])
        res.append(arr[negMaxIdx])
 
        for i in range(n):
            if (i != negMinIdx and
                i != negMaxIdx):
                res.append(arr[i])
 
        for i in range(len(res)):
            print(res[i], end = " ")
 
        print()
 
    # Case - 4:
    else:
        print("No swap required")
 
# Driver code
if __name__ == "__main__":
 
    arr = [-4, 1, 6,
           -3, -2, -1]
    n = len(arr)
    getMinimumSum(arr, n)
 
# This code is contributed by Chitranayal


C#
// C# program to find minimum sum of
// roots of a given polynomial
using System;
using System.Collections.Generic;
 
class GFG{
     
static void getMinimumSum(int[] arr, int n)
{
 
    // resultant vector
    List res = new List();
     
    // a vector that store indices of the positive
    // elements
    List pos = new List();
     
    // a vector that store indices of the negative
    // elements
    List neg = new List();
     
    for(int i = 0; i < n; i++)
    {
        if (arr[i] > 0)
            pos.Add(i);       
        else if (arr[i] < 0)
            neg.Add(i);       
    }
     
    // Case - 1:
    if (pos.Count >= 2 && neg.Count >= 2)
    {
        int posMax = Int32.MinValue, posMaxIdx = -1;
        int posMin = Int32.MaxValue, posMinIdx = -1;
         
        int negMax = Int32.MinValue, negMaxIdx = -1;
        int negMin = Int32.MaxValue, negMinIdx = -1;
         
        for(int i = 0; i < pos.Count; i++)
        {
            if (arr[pos[i]] > posMax)
            {
                posMaxIdx = pos[i];
                posMax = arr[posMaxIdx];
            }
        }
         
        for(int i = 0; i < pos.Count; i++)
        {
            if (arr[pos[i]] < posMin &&
                pos[i] != posMaxIdx)
            {
                posMinIdx = pos[i];
                posMin = arr[posMinIdx];
            }
        }
     
        for(int i = 0; i < neg.Count; i++)
        {
            if (Math.Abs(arr[neg[i]]) > negMax)
            {
                negMaxIdx = neg[i];
                negMax = Math.Abs(arr[negMaxIdx]);
            }
        }
     
        for(int i = 0; i < neg.Count; i++)
        {
            if (Math.Abs(arr[neg[i]]) < negMin &&
                             neg[i] != negMaxIdx)
            {
                negMinIdx = neg[i];
                negMin = Math.Abs(arr[negMinIdx]);
            }
        }
     
        double posVal = -1.0 * (double)posMax / (double)posMin;
        double negVal = -1.0 * (double)negMax / (double)negMin;
         
        if (posVal < negVal)
        {
            res.Add(arr[posMinIdx]);
            res.Add(arr[posMaxIdx]);
             
            for(int i = 0; i < n; i++)
            {
                if (i != posMinIdx && i != posMaxIdx)
                {
                    res.Add(arr[i]);
                }
            }
        }
        else
        {
            res.Add(arr[negMinIdx]);
            res.Add(arr[negMaxIdx]);
             
            for(int i = 0; i < n; i++)
            {
                if (i != negMinIdx && i != negMaxIdx)
                {
                    res.Add(arr[i]);
                }
            }
        }
        for(int i = 0; i < res.Count; i++)
        {
            Console.Write(res[i] + " ");
        }
        Console.WriteLine();
    }
     
    // Case - 2:
    else if (pos.Count >= 2)
    {
        int posMax = Int32.MinValue, posMaxIdx = -1;
        int posMin = Int32.MaxValue, posMinIdx = -1;
         
        for(int i = 0; i < pos.Count; i++)
        {
            if (arr[pos[i]] > posMax)
            {
                posMaxIdx = pos[i];
                posMax = arr[posMaxIdx];
            }
        }
         
        for(int i = 0; i < pos.Count; i++)
        {
            if (arr[pos[i]] < posMin &&
                    pos[i] != posMaxIdx)
            {
                posMinIdx = pos[i];
                posMin = arr[posMinIdx];
            }
        }
         
        res.Add(arr[posMinIdx]);
        res.Add(arr[posMaxIdx]);
     
        for(int i = 0; i < n; i++)
        {
            if (i != posMinIdx && i != posMaxIdx)
            {
                res.Add(arr[i]);
            }
        }
        for(int i = 0; i < res.Count; i++)
        {
            Console.Write(res[i] + " ");
        }
        Console.WriteLine();
    }
     
    // Case - 3:
    else if (neg.Count >= 2)
    {
        int negMax = Int32.MinValue, negMaxIdx = -1;
        int negMin = Int32.MaxValue, negMinIdx = -1;
         
        for(int i = 0; i < neg.Count; i++)
        {
            if (Math.Abs(arr[neg[i]]) > negMax)
            {
                negMaxIdx = neg[i];
                negMax = Math.Abs(arr[negMaxIdx]);
            }
        }
         
        for(int i = 0; i < neg.Count; i++)
        {
            if (Math.Abs(arr[neg[i]]) < negMin &&
                             neg[i] != negMaxIdx)
            {
                negMinIdx = neg[i];
                negMin = Math.Abs(arr[negMinIdx]);
            }
        }
         
        res.Add(arr[negMinIdx]);
        res.Add(arr[negMaxIdx]);
         
        for(int i = 0; i < n; i++)
            if (i != negMinIdx && i != negMaxIdx)
                res.Add(arr[i]);
         
        for(int i = 0; i < res.Count; i++)
            Console.WriteLine(res[i] + " ");
         
        Console.WriteLine();
    }
     
    // Case - 4:
    else
    {
        Console.WriteLine("No swap required");
    }
}
 
// Driver code
static public void Main()
{
    int[] arr = { -4, 1, 6, -3, -2, -1 };
    int n = arr.Length;
     
    getMinimumSum(arr, n);
}
}
 
// This code is contributed by avanitrachhadiya2155


输出:
1 6 -4 -3 -2 -1