📌  相关文章
📜  程序查找第n个可被a或b整除的项

📅  最后修改于: 2021-04-27 18:12:54             🧑  作者: Mango

给定两个整数ab 。任务是找到第N个可被以下任一项整除的项a或者b

例子 :

Input : a = 2, b = 5, N = 10
Output : 16

Input : a = 3, b = 7, N = 25
Output : 57

天真的方法:一种简单的方法是遍历从1开始的所有项,直到找到所需的第N个项,而第N个项可以被任意一个整除a或者b 。该解决方案的时间复杂度为O(N)。

高效的方法:这个想法是使用二进制搜索。在这里我们可以计算从1到1的数字num通过使用公式可被a或b整除:

 termCount= num/a + num/b - num/lcm(a, b)

lcm(a,b)的所有倍数都可以被两个整数整除ab因此我们需要删除这些条款。现在,如果可分割项的数量小于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