gcd 与 lcm

题目描述: 
                                 
G - GCD & LCM
Crawling in process... Crawling failed Time Limit:1000MS    Memory Limit:32768KB   64bit IO Format:%lld & %llu

Description

Given x and y (2 <= x <= 100,000, 2 <= y <= 1,000,000), you are   to count the number of p and q such that:

1) p and q are positive integers;

2) GCD(p, q) = x;

3) LCM(p, q) = y.


<b< body="">

Input

x and y, one line for each test.


<b< body="">

Output

Number of pairs of p and q.


<b< body="">

Sample Input

3 60


<b< body="">

Sample Output

4

 

 

题目大意:就是找出p*q=x*y,pq的对数。

用一个公式很好:(a/gcd  )* ( b/gcd)= lcm/gcd

这样子把lcm的数量级降下来了。而且

因为左边2块互质,这样子递归求解最大公约数时的层次走少了好几步。

 

program:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int x,y;
int lg;
int gcd(int  a,int  b)
{
  if(a%b==0)return b;
  return gcd(b,a%b);   
}
void sswap(int & a,int & b)
{
  int tmp=a;
  a=b;
  b=tmp;
}
int main()
{
while(scanf("%d%d",&x,&y)!=EOF)
{
      //最小公倍数一定能整除最大公约数!
      if(y%x!=0)
       {
            printf("0\n");
            continue;     
       }  
      lg=y/x; //(a/gcd  )* ( b/gcd)= lcm/gcd
      int a,b;
      int cnt=0;
      for(int i=1;i<=lg;i++)
      {
         a=i;
         if(lg%a==0)
            {
              b=lg/a; //把问题化为质数问题实在很棒
              if(a%2==0&&b%2==0)
                 continue;
              if(a<b)
                 sswap(a,b);
              
              if(gcd(a,b)==1)
                 cnt++;       
            }   
      }
     
       printf("%d\n",cnt);                                                
}
//system("pause");
return 0;}

 

总结:其实一个思想很重要:把求解的数转化成和质数有关来求解,因为质数相对合数少很多,所以这样处理问题范围减小很多!

另为什么验证素数的时候只需验证到该数的开方根呢?因为如果n可以被一个数整除,那么就必然有一个因子小于开方根,必然有一个因子大于开方根

 

因为i=a×b,a与b不能同时大于sqrt(i),为什么呢?如果a>sqrt(i),b>sqrt(i),于是a×b>sqrt(i)*sqrt(i)=i,因此就都不能整除i了!

这个问题是关于最大公约数(GCD)和最小公倍数(LCM)的算法编程问题。在编程竞赛中,常常需要编写代码来计算两个或多个整数的GCDLCM。对于这个问题【MX-X3-T3】「RiOI-4」GCDLCM 问题,我们通常需要考虑以下步骤: 1. 计算GCD:最大公约数是两个或多个整数共有约数中最大的一个。常见的算法有欧几里得算法(辗转相除法),用于计算两个数的最大公约数。 2. 计算LCM:最小公倍数是能被两个或多个整数整除的最小正整数。最小公倍数可以通过以下公式计算:LCM(a, b) = |a * b| / GCD(a, b)。 对于具体的代码实现,我们可以使用循环或递归的方式实现欧几里得算法来计算GCD,然后用GCD的结果来计算LCM。在某些编程语言中,可能有内置的库函数可以直接计算GCDLCM。 例如,在C++中,你可以使用以下代码片段: ```cpp #include <iostream> using namespace std; // 函数原型声明 int gcd(int a, int b); int lcm(int a, int b); int main() { int a, b; cin >> a >> b; // 输入两个整数 cout << gcd(a, b) << endl; // 输出最大公约数 cout << lcm(a, b) << endl; // 输出最小公倍数 return 0; } // 使用欧几里得算法计算GCD int gcd(int a, int b) { while (b != 0) { int t = b; b = a % b; a = t; } return a; } // 计算LCM,利用GCD的结果 int lcm(int a, int b) { return (a / gcd(a, b)) * b; // 先除后乘防止溢出 } ``` 这段代码中,`gcd`函数使用欧几里得算法计算两个数的最大公约数,而`lcm`函数则根据最大公约数和给定的两个数计算最小公倍数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值