📌  相关文章
📜  将给定序列转换为几何级数的最小操作数

📅  最后修改于: 2021-04-24 15:34:02             🧑  作者: Mango

给定一个由N个元素组成的序列,最多只能一次对任何一个元素执行三个操作。操作是:

  1. 将一个添加到元素。
  2. 从元素中减去一个。
  3. 保持元素不变。

对数组中的所有元素执行任何一项操作。任务是找到可以对序列执行的最小操作数(加法和减法),以便将其转换为几何级数。如果无法通过执行上述操作生成GP,则打印-1。

例子

方法这里要进行的主要观察是,任何几何级数都仅由其前两个元素唯一地确定(因为每对接下来的对之间的比率必须与由前两个元素组成的该对之间的比率相同)。由于只能进行3 * 3排列。可能的操作组合为(+1,+1),(+1,0),(+1,-1),(-1,+1),(-1,0),(-1,-1 ),(0,+1),(0,0)和(0,-1)。使用暴力破解所有这9个排列并检查它们是否在线性时间内形成GP,将为我们提供答案。导致组合出现在GP中的最少操作将是答案。

下面是上述方法的实现:

C++
// C++ program to find minimum number
// of operations to convert a given
// sequence to an Geometric Progression
#include 
using namespace std;
  
// Function to print the GP series
void construct(int n, pair ans_pair)
{
    // Check for possibility
    if (ans_pair.first == -1) {
        cout << "Not possible";
        return;
    }
    double a1 = ans_pair.first;
    double a2 = ans_pair.second;
    double r = a2 / a1;
  
    cout << "The resultant sequence is:\n";
    for (int i = 1; i <= n; i++) {
        double ai = a1 * pow(r, i - 1);
        cout << ai << " ";
    }
}
  
// Function for getting the Arithmetic Progression
void findMinimumOperations(double* a, int n)
{
    int ans = INT_MAX;
    // The array c describes all the given set of
    // possible operations.
    int c[] = { -1, 0, 1 };
    // Size of c
    int possiblities = 3;
  
    // candidate answer
    int pos1 = -1, pos2 = -1;
  
    // loop through all the permutations of the first two
    // elements.
    for (int i = 0; i < possiblities; i++) {
        for (int j = 0; j < possiblities; j++) {
  
            // a1 and a2 are the candidate first two elements
            // of the possible GP.
            double a1 = a[1] + c[i];
            double a2 = a[2] + c[j];
  
            // temp stores the current answer, including the
            // modification of the first two elements.
            int temp = abs(a1 - a[1]) + abs(a2 - a[2]);
  
            if (a1 == 0 || a2 == 0)
                continue;
  
            // common ratio of the possible GP
            double r = a2 / a1;
  
            // To check if the chosen set is valid, and id yes
            // find the number of operations it takes.
            for (int pos = 3; pos <= n; pos++) {
  
                // ai is value of a[i] according to the assumed
                // first two elements a1, a2
                // ith element of an GP = a1*((a2-a1)^(i-1))
                double ai = a1 * pow(r, pos - 1);
  
                // Check for the "proposed" element to be only
                // differing by one
                if (a[pos] == ai) {
                    continue;
                }
                else if (a[pos] + 1 == ai || a[pos] - 1 == ai) {
                    temp++;
                }
                else {
                    temp = INT_MAX; // set the temporary ans
                    break; // to infinity and break
                }
            }
  
            // update answer
            if (temp < ans) {
                ans = temp;
                pos1 = a1;
                pos2 = a2;
            }
        }
    }
    if (ans == -1) {
        cout << "-1";
        return;
    }
  
    cout << "Minimum Number of Operations are " << ans << "\n";
    pair ans_pair = { pos1, pos2 };
  
    // Calling function to print the sequence
    construct(n, ans_pair);
}
  
// Driver Code
int main()
{
  
    // array is 1-indexed, with a[0] = 0
    // for the sake of simplicity
    double a[] = { 0, 7, 20, 49, 125 };
  
    int n = sizeof(a) / sizeof(a[0]);
  
    // Function to print the minimum operations
    // and the sequence of elements
    findMinimumOperations(a, n - 1);
    return 0;
}


Java
// Java program to find minimum number
// of operations to convert a given
// sequence to an Geometric Progression
import java.util.*;
  
class GFG
{
      
static class pair
{ 
    double first, second; 
    public pair(double first, double second) 
    { 
        this.first = first; 
        this.second = second; 
    } 
} 
// Function to print the GP series
static void construct(int n, pair ans_pair)
{
    // Check for possibility
    if (ans_pair.first == -1)
    {
        System.out.print("Not possible");
        return;
    }
    double a1 = ans_pair.first;
    double a2 = ans_pair.second;
    double r = a2 / a1;
  
    System.out.print("The resultant sequence is:\n");
    for (int i = 1; i <= n; i++)
    {
        int ai = (int) (a1 * Math.pow(r, i - 1));
        System.out.print(ai + " ");
    }
}
  
// Function for getting the Arithmetic Progression
static void findMinimumOperations(double []a, int n)
{
    int ans = Integer.MAX_VALUE;
      
    // The array c describes all the given set of
    // possible operations.
    int c[] = { -1, 0, 1 };
      
    // Size of c
    int possiblities = 3;
  
    // candidate answer
    int pos1 = -1, pos2 = -1;
  
    // loop through all the permutations of the first two
    // elements.
    for (int i = 0; i < possiblities; i++) 
    {
        for (int j = 0; j < possiblities; j++) 
        {
  
            // a1 and a2 are the candidate first two elements
            // of the possible GP.
            double a1 = a[1] + c[i];
            double a2 = a[2] + c[j];
  
            // temp stores the current answer, including the
            // modification of the first two elements.
            int temp = (int) (Math.abs(a1 - a[1]) + Math.abs(a2 - a[2]));
  
            if (a1 == 0 || a2 == 0)
                continue;
  
            // common ratio of the possible GP
            double r = a2 / a1;
  
            // To check if the chosen set is valid, and id yes
            // find the number of operations it takes.
            for (int pos = 3; pos <= n; pos++)
            {
  
                // ai is value of a[i] according to the assumed
                // first two elements a1, a2
                // ith element of an GP = a1*((a2-a1)^(i-1))
                double ai = a1 * Math.pow(r, pos - 1);
  
                // Check for the "proposed" element to be only
                // differing by one
                if (a[pos] == ai)
                {
                    continue;
                }
                else if (a[pos] + 1 == ai || a[pos] - 1 == ai)
                {
                    temp++;
                }
                else
                {
                    temp = Integer.MAX_VALUE; // set the temporary ans
                    break; // to infinity and break
                }
            }
  
            // update answer
            if (temp < ans) 
            {
                ans = temp;
                pos1 = (int) a1;
                pos2 = (int) a2;
            }
        }
    }
    if (ans == -1) 
    {
        System.out.print("-1");
        return;
    }
  
    System.out.print("Minimum Number of Operations are " + ans+ "\n");
    pair ans_pair = new pair( pos1, pos2 );
  
    // Calling function to print the sequence
    construct(n, ans_pair);
}
  
// Driver Code
public static void main(String[] args)
{
  
    // array is 1-indexed, with a[0] = 0
    // for the sake of simplicity
    double a[] = { 0, 7, 20, 49, 125 };
  
    int n = a.length;
  
    // Function to print the minimum operations
    // and the sequence of elements
    findMinimumOperations(a, n - 1);
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python program to find minimum number
# of operations to convert a given
# sequence to an Geometric Progression
from sys import maxsize as INT_MAX
  
# Function to print the GP series
def construct(n: int, ans_pair: tuple):
  
    # Check for possibility
    if ans_pair[0] == -1:
        print("Not possible")
        return
  
    a1 = ans_pair[0]
    a2 = ans_pair[1]
    r = a2 / a1
  
    print("The resultant sequence is")
    for i in range(1, n + 1):
        ai = a1 * pow(r, i - 1)
        print(int(ai), end=" ")
  
# Function for getting the Arithmetic Progression
def findMinimumOperations(a: list, n: int):
    ans = INT_MAX
  
    # The array c describes all the given set of
    # possible operations.
    c = [-1, 0, 1]
  
    # Size of c
    possibilities = 3
  
    # candidate answer
    pos1 = -1
    pos2 = -1
  
    # loop through all the permutations of the first two
    # elements.
    for i in range(possibilities):
        for j in range(possibilities):
  
            # a1 and a2 are the candidate first two elements
            # of the possible GP.
            a1 = a[1] + c[i]
            a2 = a[2] + c[j]
  
            # temp stores the current answer, including the
            # modification of the first two elements.
            temp = abs(a1 - a[1]) + abs(a2 - a[2])
  
            if a1 == 0 or a2 == 0:
                continue
  
            # common ratio of the possible GP
            r = a2 / a1
  
            # To check if the chosen set is valid, and id yes
            # find the number of operations it takes.
            for pos in range(3, n + 1):
  
                # ai is value of a[i] according to the assumed
                # first two elements a1, a2
                # ith element of an GP = a1*((a2-a1)^(i-1))
                ai = a1 * pow(r, pos - 1)
  
                # Check for the "proposed" element to be only
                # differing by one
                if a[pos] == ai:
                    continue
                elif a[pos] + 1 == ai or a[pos] - 1 == ai:
                    temp += 1
                else:
                    temp = INT_MAX # set the temporary ans
                    break # to infinity and break
  
            # update answer
            if temp < ans:
                ans = temp
                pos1 = a1
                pos2 = a2
    if ans == -1:
        print("-1")
        return
  
    print("Minimum number of Operations are", ans)
    ans_pair = (pos1, pos2)
  
    # Calling function to print the sequence
    construct(n, ans_pair)
  
# Driver Code
if __name__ == "__main__":
  
    # array is 1-indexed, with a[0] = 0
    # for the sake of simplicity
    a = [0, 7, 20, 49, 125]
    n = len(a)
  
    # Function to print the minimum operations
    # and the sequence of elements
    findMinimumOperations(a, n - 1)
  
# This code is contributed by
# sanjeev2552


C#
// C# program to find minimum number
// of operations to convert a given
// sequence to an Geometric Progression
using System;
  
class GFG
{
      
class pair
{ 
    public double first, second; 
    public pair(double first, double second) 
    { 
        this.first = first; 
        this.second = second; 
    } 
} 
  
// Function to print the GP series
static void construct(int n, pair ans_pair)
{
    // Check for possibility
    if (ans_pair.first == -1)
    {
        Console.Write("Not possible");
        return;
    }
    double a1 = ans_pair.first;
    double a2 = ans_pair.second;
    double r = a2 / a1;
  
    Console.Write("The resultant sequence is:\n");
    for (int i = 1; i <= n; i++)
    {
        int ai = (int) (a1 * Math.Pow(r, i - 1));
        Console.Write(ai + " ");
    }
}
  
// Function for getting the Arithmetic Progression
static void findMinimumOperations(double []a, int n)
{
    int ans = int.MaxValue;
      
    // The array c describes all the given set of
    // possible operations.
    int []c = { -1, 0, 1 };
      
    // Size of c
    int possiblities = 3;
  
    // candidate answer
    int pos1 = -1, pos2 = -1;
  
    // loop through all the permutations of the first two
    // elements.
    for (int i = 0; i < possiblities; i++) 
    {
        for (int j = 0; j < possiblities; j++) 
        {
  
            // a1 and a2 are the candidate first two elements
            // of the possible GP.
            double a1 = a[1] + c[i];
            double a2 = a[2] + c[j];
  
            // temp stores the current answer, including the
            // modification of the first two elements.
            int temp = (int) (Math.Abs(a1 - a[1]) + Math.Abs(a2 - a[2]));
  
            if (a1 == 0 || a2 == 0)
                continue;
  
            // common ratio of the possible GP
            double r = a2 / a1;
  
            // To check if the chosen set is valid, and id yes
            // find the number of operations it takes.
            for (int pos = 3; pos <= n; pos++)
            {
  
                // ai is value of a[i] according to the assumed
                // first two elements a1, a2
                // ith element of an GP = a1*((a2-a1)^(i-1))
                double ai = a1 * Math.Pow(r, pos - 1);
  
                // Check for the "proposed" element to be only
                // differing by one
                if (a[pos] == ai)
                {
                    continue;
                }
                else if (a[pos] + 1 == ai || a[pos] - 1 == ai)
                {
                    temp++;
                }
                else
                {
                    temp = int.MaxValue; // set the temporary ans
                    break; // to infinity and break
                }
            }
  
            // update answer
            if (temp < ans) 
            {
                ans = temp;
                pos1 = (int) a1;
                pos2 = (int) a2;
            }
        }
    }
    if (ans == -1) 
    {
        Console.Write("-1");
        return;
    }
  
    Console.Write("Minimum Number of Operations are " + ans+ "\n");
    pair ans_pair = new pair( pos1, pos2 );
  
    // Calling function to print the sequence
    construct(n, ans_pair);
}
  
// Driver Code
public static void Main(String[] args)
{
  
    // array is 1-indexed, with a[0] = 0
    // for the sake of simplicity
    double []a = { 0, 7, 20, 49, 125 };
  
    int n = a.Length;
  
    // Function to print the minimum operations
    // and the sequence of elements
    findMinimumOperations(a, n - 1);
}
}
  
// This code is contributed by Rajput-Ji


输出:
Minimum Number of Operations are 2
The resultant sequence is:
8 20 50 125

时间复杂度:O(9 * N)