从给定序列 Y 生成序列 X 使得 Yi = gcd(X1, X2 , ... , Xi)
给定一个大小为N的序列Y ,其中:
Yi = gcd(X1, X2, X3, . . ., Xi ) of some sequence X.
任务是找到这样的序列X ,如果任何这样的 X 是可能的。
注意:如果 X 存在,则 X 可能有多个值。生成任何一个就足够了。
例子:
Input: N = 2, Y = [4, 2]
Output: [4, 2]
Explanation: Y0 = gcd(X0) = X0 = 4. And gcd(4, 2) = 2 = Y1.
Input: [1, 3]
Output: -1
Explanation: No such sequence can be formed.
方法:可以根据以下观察解决问题:
- Y的第 i 个元素 = gcd(X 1 , X 2 , X 3 , . . ., X i ) 和 Y 的第 (i+1) 个元素 = gcd(X 1 , X 2 , X 3 , . . ., X i, X i+1 )。
- 所以 Y 的第 (i+1) 个元素可以写为 gcd(gcd(X 1 , X 2 , X 3 , . . ., X i ), X i+1 ) ——-(1) 即 gcd( a, b, c) = gcd( gcd(a, b), c)。
- 所以 Y 的第 (i+1) 个元素是等式 1 中的gcd( Y 的第 i 个元素,X(i+1)) 。
- 因此,Y 的第 (i+1) 个元素必须是 Y的第 i 个元素的因子,因为两个元素的 gcd 是两个元素的除数。
- 由于 Y 的第 (i+1) 个元素除以 Y 的第 i 个元素, gcd( 第 i 个元素,第 (i+1) 个元素)总是等于第 (i+1) 个元素。
按照下图进行操作:
Illustration:
For example: N = 2, Y = {4, 2}
- X[0] = Y[0] = 4 because any number is GCD of itself.
- Y[1] = GCD(X[0], X[1]). Now GCD(X[0]) = Y[0]. So Y[1] = GCD(Y[0], X[1]). Therefore Y[1] should be a factor of Y[0].
- In the given example 2 is a factor of 4. So forming a sequence X is possible and X[1] can be same as Y[1].
Assigning X[1] = 2 satisfies GCD (X[0, X[1]) = Y[1] = 2. - So the final sequence X is {4, 2}.
所以根据上面的观察,按照下面提到的步骤来解决问题:
- 从序列的开头开始遍历 Y。
- 如果在给定的序列 Y 中有任何第 (i+1) 个元素不分割第 i 个元素,则无法生成序列 X。
- 如果第(i+1)个元素整除第i个元素,则存在一个序列X,由Y的第(i+1)个元素的上述结论可以找到
是 gcd( Y 的第 i 个元素,X i+1 ) 并且X i+1 = Y i+1是X i+1的可能值。
下面是该方法的实现:
C++
// C++ Program to implement above approach
#include
using namespace std;
// Euclidean theorem to find gcd
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
// Function to check if it is possible
// to generate lost sequence X
void checkforX(int Y[], int N)
{
int cur_gcd = Y[0];
bool Xexist = true;
// Loop to check existence of X
for (int i = 1; i < N; i++) {
cur_gcd = gcd(cur_gcd, Y[i]);
if (cur_gcd != Y[i]) {
Xexist = false;
break;
}
}
// Sequence X is found
if (Xexist) {
// Loop to generate X
for (int i = 0; i < N; i++)
cout << Y[i] << ' ';
}
// Sequence X can't be generated
else {
cout << -1 << endl;
}
}
// Driver code
int main()
{
int N = 2;
// Sequence Y of size 2
int Y[] = { 4, 2 };
checkforX(Y, N);
return 0;
}
C
// C program to implement above approach
#include
// Euclidean theorem to calculate gcd
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
// Function to check if it is possible
// to generate lost sequence X
void checkforX(int Y[], int N)
{
int cur_gcd = Y[0];
int Xexist = 1;
// Loop to check existence of X
for (int i = 1; i < N; i++) {
cur_gcd = gcd(cur_gcd, Y[i]);
if (cur_gcd != Y[i]) {
Xexist = 0;
break;
}
}
// Sequence X is found
if (Xexist) {
// Loop to generate X
for (int i = 0; i < N; i++)
printf("%d ", Y[i]);
}
// Sequence X can't be generated
else {
printf("-1");
}
}
// Driver code
int main()
{
int N = 2;
// Sequence Y of size 2
int Y[] = { 4, 2 };
checkforX(Y, N);
return 0;
}
Java
// Java Program to implement above approach
import java.util.*;
class GFG{
// Euclidean theorem to find gcd
static int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
// Function to check if it is possible
// to generate lost sequence X
static void checkforX(int Y[], int N)
{
int cur_gcd = Y[0];
boolean Xexist = true;
// Loop to check existence of X
for (int i = 1; i < N; i++) {
cur_gcd = gcd(cur_gcd, Y[i]);
if (cur_gcd != Y[i]) {
Xexist = false;
break;
}
}
// Sequence X is found
if (Xexist) {
// Loop to generate X
for (int i = 0; i < N; i++)
System.out.print(Y[i] +" ");
}
// Sequence X can't be generated
else {
System.out.print(-1 +"\n");
}
}
// Driver code
public static void main(String[] args)
{
int N = 2;
// Sequence Y of size 2
int Y[] = { 4, 2 };
checkforX(Y, N);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python code for the above approach
# Euclidean theorem to find gcd
def gcd(a, b):
if (b == 0):
return a
return gcd(b, a % b)
# Function to check if it is possible
# to generate lost sequence X
def checkforX(Y, N):
cur_gcd = Y[0]
Xexist = True
# Loop to check existence of X
for i in range(1, N):
cur_gcd = gcd(cur_gcd, Y[i])
if (cur_gcd != Y[i]):
Xexist = False
break
# Sequence X is found
if (Xexist):
# Loop to generate X
for i in range(N):
print(Y[i], end=' ')
# Sequence X can't be generated
else:
print(-1)
# Driver code
N = 2
# Sequence Y of size 2
Y = [4, 2]
checkforX(Y, N)
# This code is contributed by gfgking
C#
// C# Program to implement above approach
using System;
class GFG
{
// Euclidean theorem to find gcd
static int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
// Function to check if it is possible
// to generate lost sequence X
static void checkforX(int []Y, int N)
{
int cur_gcd = Y[0];
bool Xexist = true;
// Loop to check existence of X
for (int i = 1; i < N; i++) {
cur_gcd = gcd(cur_gcd, Y[i]);
if (cur_gcd != Y[i]) {
Xexist = false;
break;
}
}
// Sequence X is found
if (Xexist) {
// Loop to generate X
for (int i = 0; i < N; i++)
Console.Write(Y[i] + " ");
}
// Sequence X can't be generated
else {
Console.Write(-1);
}
}
// Driver code
public static void Main()
{
int N = 2;
// Sequence Y of size 2
int []Y = { 4, 2 };
checkforX(Y, N);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
4 2
时间复杂度: O(N)
辅助空间: O(1)