最小公倍数与最大公约数问题(NOIP竞赛原题)

 最小公倍数与最大公约数问题:
                            
 描述 Description   
     输入二个正整数x0,y0(2≤x0≤100000,2≤y0≤1000000),求出满足下列条件的P、Q的个数。
  条件:1.P、Q是正整数
      2.要求P、Q以xO为最大公约数,以yO为最小公倍数。
  试求,满足条件的所有可能的两个正整数的个数。 
/*

 最小公倍数与最大公约数问题:
                            
 描述 Description   
     输入二个正整数x0,y0(2≤x0≤100000,2≤y0≤1000000),求出满足下列条件的P、Q的个数。
  条件:1.P、Q是正整数
      2.要求P、Q以xO为最大公约数,以yO为最小公倍数。
  试求,满足条件的所有可能的两个正整数的个数。 
   
   
 输入格式 Input Format  
   两个正整数  
   
   
 输出格式 Output Format  
   满足条件的所有可能的两个正整数的个数 

*/
/*
搜索法:
根据最小公倍数的定义可知:
若:x0 为 x,y 的最大公约数,y0 为x,y 的最小公倍数,
由定义得:
(x/x0)*(y/x0)*x0 = x*y/x0 = y0 ;
即:x0*y0 = x * y ;
设:i=x/x0,j=y/xo, 则: i*j = y0/x0 且: i,j互质,因此:我们只要找到所有
满足条件的:i,j即可
由于具有对称性,因此只要求: 1--sqrt(y0/x0) 范围内的结果,然如乘以2就OK了

*/
/*
NO.1
*/

#include 
< stdio.h >

int  gcd ( int  a, int  b)
{
    
if  ( b  ==   0 )
    
return  a ;
    
else
    
return  gcd(b,a % b) ;
}

int  is_fu_ze( int  a, int  b)
{
    
if (gcd(a,b)  ==   1 )
    
return   1  ;
    
else
    
return   0  ;
}

int  main( void )
{
    
long  x0,y0,i,j,k,total = 0 ;
    
    scanf(
" %ld %ld " , & x0, & y0);
    
    
if ( y0  %  x0  !=   0   ||  x0  ==  y0)
    {
       ( x0 
==  y0)  ?  printf( " 1 " ) : printf( " 0 " );
       
return   0  ;
    }
    
    k 
=  y0  /  x0 ;
    j 
=  ( int )sqrt(( double )k) ;
    
for (i = 1  ; i <=  j ; i ++ )
    
if ( k  %  i  ==   0   &&  is_fu_ze(i,k / i) )
    {
        total 
++  ;
        printf(
" %ld %ld " ,i,k / i);
    }
    
    
    printf(
" total = %ld " ,total * 2 ) ;
    
    system(
" pause " );
    
return   0  ;
}
/*
NO.2  
*/  
/* 找规律法:
n = 2^k ; 其中K是YO/X0的质因子个数
*/
       #include 
< stdio.h >
       
       
int  main( void )
       {
           
long  x0,y0 ;
           
long    k,total = 0 ;
           
int  i,j,num = 0  ;
           
           scanf(
" %d %d " , & x0, & y0);
           
           
if  ( y0  %  x0  !=   0   ||  y0  ==  x0)
           {
                
               ( x0 
==  y0)  ?  printf( " 1 " ) : printf( " 0 " );
                
return   0  ;
           }
           
           k 
=  y0 / x0 ;
           
           j 
=   2
           
           
while  ( 1 )
           {
                 
if (k  %  j  ==   0 )
                 {
                      
                     
while (k  %  j  ==   0   &&  k  !=  j)
                     k 
/=  j ;
                     num 
++  ;
                     
if (k  ==  j)
                     
break  ;
                 }
                 
                 j 
++  ;
           }
           
           total 
=   1  ;
           
for (i = 1  ; i <=  num ; i ++ )
           total 
*=   2  ;
           printf(
" %ld " ,total);
            
           
return   0  ;
       }
 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值