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

📅  最后修改于: 2021-10-26 05:54:07             🧑  作者: 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 possibilities = 3;
 
    // candidate answer
    int pos1 = -1, pos2 = -1;
 
    // loop through all the permutations of the first two
    // elements.
    for (int i = 0; i < possibilities; i++) {
        for (int j = 0; j < possibilities; 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 possibilities = 3;
 
    // candidate answer
    int pos1 = -1, pos2 = -1;
 
    // loop through all the permutations of the first two
    // elements.
    for (int i = 0; i < possibilities; i++)
    {
        for (int j = 0; j < possibilities; 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 possibilities = 3;
 
    // candidate answer
    int pos1 = -1, pos2 = -1;
 
    // loop through all the permutations of the first two
    // elements.
    for (int i = 0; i < possibilities; i++)
    {
        for (int j = 0; j < possibilities; 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


Javascript


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

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

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程