给定两个整数和 。任务是找到第N个可被以下任一项整除的项或者 。
例子 :
Input : a = 2, b = 5, N = 10
Output : 16
Input : a = 3, b = 7, N = 25
Output : 57
天真的方法:一种简单的方法是遍历从1开始的所有项,直到找到所需的第N个项,而第N个项可以被任意一个整除或者 。该解决方案的时间复杂度为O(N)。
高效的方法:这个想法是使用二进制搜索。在这里我们可以计算从1到1的数字通过使用公式可被a或b整除:
lcm(a,b)的所有倍数都可以被两个整数整除和因此我们需要删除这些条款。现在,如果可分割项的数量小于N,我们将增加二分搜索的低位,否则将减小较高值,直到可分割项的数量等于N。
以下是上述想法的实现:
C++
// C++ program to find nth term
// divisible by a or b
#include
using namespace std;
// Function to return
// gcd of a and b
int gcd(int a, int b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
// Function to calculate how many numbers
// from 1 to num are divisible by a or b
int divTermCount(int a, int b, int lcm, int num)
{
// calculate number of terms divisible by a and
// by b then, remove the terms which is are
// divisible by both a and b
return num / a + num / b - num / lcm;
}
// Binary search to find the nth term
// divisible by a or b
int findNthTerm(int a, int b, int n)
{
// set low to 1 and high to max(a, b)*n, here
// we have taken high as 10^18
int low = 1, high = INT_MAX, mid;
int lcm = (a * b) / gcd(a, b);
while (low < high) {
mid = low + (high - low) / 2;
// if the current term is less than
// n then we need to increase low
// to mid + 1
if (divTermCount(a, b, lcm, mid) < n)
low = mid + 1;
// if current term is greater than equal to
// n then high = mid
else
high = mid;
}
return low;
}
// Driver code
int main()
{
int a = 2, b = 5, n = 10;
cout << findNthTerm(a, b, n) << endl;
return 0;
}
Java
// Java program to find nth term
// divisible by a or b
class GFG
{
// Function to return
// gcd of a and b
static int gcd(int a, int b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
// Function to calculate how many numbers
// from 1 to num are divisible by a or b
static int divTermCount(int a, int b,
int lcm, int num)
{
// calculate number of terms
// divisible by a and by b then,
// remove the terms which is are
// divisible by both a and b
return num / a + num / b - num / lcm;
}
// Binary search to find the
// nth term divisible by a or b
static int findNthTerm(int a, int b, int n)
{
// set low to 1 and high to max(a, b)*n,
// here we have taken high as 10^18
int low = 1, high = Integer.MAX_VALUE, mid;
int lcm = (a * b) / gcd(a, b);
while (low < high)
{
mid = low + (high - low) / 2;
// if the current term is less
// than n then we need to increase
// low to mid + 1
if (divTermCount(a, b, lcm, mid) < n)
low = mid + 1;
// if current term is greater
// than equal to n then high = mid
else
high = mid;
}
return low;
}
// Driver code
public static void main (String[] args)
{
int a = 2, b = 5, n = 10;
System.out.println(findNthTerm(a, b, n));
}
}
// This code is contributed by Smitha
Python3
# Python 3 program to find nth term
# divisible by a or b
import sys
# Function to return gcd of a and b
def gcd(a, b):
if a == 0:
return b
return gcd(b % a, a)
# Function to calculate how many numbers
# from 1 to num are divisible by a or b
def divTermCount(a, b, lcm, num):
# calculate number of terms divisible
# by a and by b then, remove the terms
# which are divisible by both a and b
return num // a + num // b - num // lcm
# Binary search to find the nth term
# divisible by a or b
def findNthTerm(a, b, n):
# set low to 1 and high to max(a, b)*n,
# here we have taken high as 10^18
low = 1; high = sys.maxsize
lcm = (a * b) // gcd(a, b)
while low < high:
mid = low + (high - low) // 2
# if the current term is less
# than n then we need to increase
# low to mid + 1
if divTermCount(a, b, lcm, mid) < n:
low = mid + 1
# if current term is greater
# than equal to n then high = mid
else:
high = mid
return low
# Driver code
a = 2; b = 5; n = 10
print(findNthTerm(a, b, n))
# This code is contributed by Shrikant13
C#
// C# program to find nth term
// divisible by a or b
using System;
class GFG
{
// Function to return gcd of a and b
static int gcd(int a, int b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
// Function to calculate how many numbers
// from 1 to num are divisible by a or b
static int divTermCount(int a, int b,
int lcm, int num)
{
// calculate number of terms
// divisible by a and by b then,
// remove the terms which is are
// divisible by both a and b
return num / a + num / b - num / lcm;
}
// Binary search to find the
// nth term divisible by a or b
static int findNthTerm(int a, int b, int n)
{
// set low to 1 and high to max(a, b)*n,
// here we have taken high as 10^18
int low = 1, high = int.MaxValue, mid;
int lcm = (a * b) / gcd(a, b);
while (low < high)
{
mid = low + (high - low) / 2;
// if the current term is less
// than n then we need to increase
// low to mid + 1
if (divTermCount(a, b, lcm, mid) < n)
low = mid + 1;
// if current term is greater
// than equal to n then high = mid
else
high = mid;
}
return low;
}
// Driver code
static public void Main ()
{
int a = 2, b = 5, n = 10;
Console.WriteLine(findNthTerm(a, b, n));
}
}
// This code is contributed by Sach_Code
输出:
16