给定一个由N个正整数组成的数组arr [] ,任务是检查在将给定数组的所有子集的所有元素乘以任何整数之后,是否可以将其总和减小为1 。如果无法这样做,请打印“否” 。否则,打印“是” 。
例子:
Input: arr[] = {29, 6, 4, 10}
Output: Yes
Explanation:
Choose a subset {29, 6, 10} and multiply each corresponding element by {1, -3, -1}.
Therefore, sum of the subset = 29 * (1) + 6 * (-3) + 10 * (-1) = 29 – 18 – 10 = 1.
Therefore, print “Yes”.
Input: arr[] = {6, 3, 9}
Output: No
天真的方法:最简单的方法是生成给定数组的所有可能的子集,并且如果数组中存在任何子集,以使其元素的总和乘以任何整数后得出1,则打印“是” 。否则,打印“否” 。
时间复杂度: O(N * 2 N )
辅助空间: O(1)
高效的方法:上述方法也可以通过使用Bezout的身份(Bezout引理)进行优化,该身份表示如果任意两个整数a和b的GCD等于d ,则存在整数x和y ,使得a * x + b * y = d 。
因此,我们的想法是检查给定数组arr []的GCD是否可以设为1 。因此,为了满足给定条件,必须存在GCD为1的任何两个元素,然后数组的GCD等于1 。因此,打印“是” 。否则,打印“否” 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to return gcd of a and b
int gcd(int a, int b)
{
// Base Case
if (a == 0)
return b;
// Find the GCD recursively
return gcd(b % a, a);
}
// Function to calculate the GCD
// of the array arr[]
int findGCDofArray(int arr[], int N)
{
// Stores the GCD of array
int g = 0;
// Travese the array arr[]
for (int i = 0; i < N; i++) {
// Update gcd of the array
g = gcd(g, arr[i]);
// If gcd is 1, then return 1
if (g == 1) {
return 1;
}
}
// Return the resultant GCD
return g;
}
// Function to check if a subset satisfying
// the given condition exists or not
void findSubset(int arr[], int N)
{
// Calculate the gcd of the array
int gcd = findGCDofArray(arr, N);
// If gcd is 1, then print Yes
if (gcd == 1) {
cout << "Yes";
}
// Otherwise, print No
else {
cout << "No";
}
}
// Driver Code
int main()
{
int arr[] = { 29, 6, 4, 10 };
int N = sizeof(arr) / sizeof(arr[0]);
findSubset(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG
{
// Function to return gcd of a and b
static int gcd(int a, int b)
{
// Base Case
if (a == 0)
return b;
// Find the GCD recursively
return gcd(b % a, a);
}
// Function to calculate the GCD
// of the array arr[]
static int findGCDofArray(int arr[], int N)
{
// Stores the GCD of array
int g = 0;
// Travese the array arr[]
for (int i = 0; i < N; i++)
{
// Update gcd of the array
g = gcd(g, arr[i]);
// If gcd is 1, then return 1
if (g == 1) {
return 1;
}
}
// Return the resultant GCD
return g;
}
// Function to check if a subset satisfying
// the given condition exists or not
static void findSubset(int arr[], int N)
{
// Calculate the gcd of the array
int gcd = findGCDofArray(arr, N);
// If gcd is 1, then print Yes
if (gcd == 1) {
System.out.println("Yes");
}
// Otherwise, print No
else {
System.out.println("No");
}
}
// Driver code
public static void main(String[] args)
{
// Given array
int arr[] = { 29, 6, 4, 10 };
// length of the array
int N = arr.length;
// function call
findSubset(arr, N);
}
}
// This code is contributed by Kingash.
Python3
# Python3 program for the above approach
# Function to return gcd of a and b
def gcd(a, b):
# Base Case
if (a == 0):
return b
# Find the GCD recursively
return gcd(b % a, a)
# Function to calculate the GCD
# of the array arr[]
def findGCDofArray(arr, N):
# Stores the GCD of array
g = 0
# Travese the array arr[]
for i in range(N):
# Update gcd of the array
g = gcd(g, arr[i])
# If gcd is 1, then return 1
if (g == 1):
return 1
# Return the resultant GCD
return g
# Function to check if a subset satisfying
# the given condition exists or not
def findSubset(arr, N):
# Calculate the gcd of the array
gcd = findGCDofArray(arr, N)
# If gcd is 1, then prYes
if (gcd == 1):
print("Yes")
# Otherwise, prNo
else:
print("No")
# Driver Code
if __name__ == '__main__':
arr = [29, 6, 4, 10]
N = len(arr)
findSubset(arr, N)
# This code is contributed by mohit kumar 29.
C#
// C# program for the above approach
using System;
class GFG
{
// Function to return gcd of a and b
static int gcd(int a, int b)
{
// Base Case
if (a == 0)
return b;
// Find the GCD recursively
return gcd(b % a, a);
}
// Function to calculate the GCD
// of the array arr[]
static int findGCDofArray(int[] arr, int N)
{
// Stores the GCD of array
int g = 0;
// Travese the array arr[]
for (int i = 0; i < N; i++) {
// Update gcd of the array
g = gcd(g, arr[i]);
// If gcd is 1, then return 1
if (g == 1) {
return 1;
}
}
// Return the resultant GCD
return g;
}
// Function to check if a subset satisfying
// the given condition exists or not
static void findSubset(int[] arr, int N)
{
// Calculate the gcd of the array
int gcd = findGCDofArray(arr, N);
// If gcd is 1, then print Yes
if (gcd == 1) {
Console.Write("Yes");
}
// Otherwise, print No
else {
Console.Write("No");
}
}
// Driver code
public static void Main(String[] args)
{
int[] arr = { 29, 6, 4, 10 };
int N = arr.Length;
findSubset(arr, N);
}
}
// This code is contributed by shivani
Yes
时间复杂度: O(N * log(M)),其中M是数组中最小的元素。
辅助空间: O(1)