NOIP 2001-2——最大公约数和最小公倍数问题(简单推导/分解质因数)

来源:互联网 发布:手游运营数据分析 编辑:程序博客网 时间:2024/05/18 10:23
问题描述
输入二个正整数x0,y0(2<=x0<100000,2<=y0<=1000000),求出满足下列条件的P,Q的个数
条件:  1.P,A是正整数
2.要求P,Q以x0为最大公约数,以y0为最小公倍数.
试求:满足条件的所有可能的两个正整数的个数.
样例
输入:x0=3   yo=60
输出:4
说明(不用输出)此时的  P  Q  分别为:
    3   60
15      12
12      15
60       3

所以:满足条件的所有可能的两个正整数的个数共4种.

gcd(p,q)=x0,lcm(p,q)=p*q/gcd(p,q)=y0  => 即满足p*q==x0*y0且p%x0==q%x0==0,枚举在区间[x0,y0]的p(x0的倍数),判断gcd(p/x0,q/x0)是否为1 

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
const int maxn = 300005;
const int mod =1e9+7;
int n,m;
ll gcd(ll a,ll b)
{
    if(b==0)return a;
    return gcd(b,a%b);
}
int main()
{
    int i,j,k,t;
    ll x0,y0;
    ll cnt=0;
    cin>>x0>>y0;
    if(y0%x0)
    {
        cout<<0<<endl;
    }
    else
    {
        for(ll p=x0; p<=y0; p+=x0)
        {
            ll q=y0*x0/p;
            if(q%x0==0&&p*q==x0*y0)
            {
                if(gcd(p/x0,q/x0)==1)
                    cnt++;
            }
        }
        cout<<cnt<<endl;
    }
    return 0;
}

分解质因数(相当于根据公约数倍增,组合这些倍数)
#include <iostream>
using namespace std;
int main()
{
    int x0,y0;
    cin>>x0>>y0;
    if(y0%x0!=0) //如果y0不能整除x0
    {
        cout<<0;
        return 0;
    }
    int ans=y0/x0;
    int a=2;
    int num[1000];
    int b=0;
    do            //把y0除以x0的数进行分解质因数
    {
        if(ans%a==0)              //找到约数
        {
            b++;            //约数+1
            ans=ans/a;
            num[b]=a;            //把约数塞到数组里
        }
        else a++;
    }
    while(ans!=1);
    /*if(b==1)             //如果只有一个约数(素数)
    {


        cout<<"2";
    return 0;
    }
    */
    int total=b;           //b的值赋给total
    for(int x=1; x<=b; x++)
    {
        if(num[x]==0)
            continue;
        for(int y=x+1; y<=b; y++)
        {
            if(num[x]==num[y])          //将数组里的质因数去重
            {
                total--;
                num[y]=0;
            }
        }
    }
    if(b==1)cout<<2;
    else cout<<(((total+1)*total/2)+1);//去重之后的数组类似于{2,3,5},总数事实上是2,3,5,2*3,2*5,3*5,2*3*5,因此用到等差数列
    return 0;
}


0 0
原创粉丝点击