题目1493:公约数

时间限制:1秒
内存限制:32 兆
特殊判题:
提交:3863
解决:752



 
题目描述:

给定两个正整数a,b(1<=a,b<=100000000),计算他们公约数的个数。
如给定正整数8和16,他们的公约数有:1、2、4、8,所以输出为4。

输入:

输入包含多组测试数据,每组测试数据一行,包含两个整数a,b。

输出:

对于每组测试数据,输出为一个整数,表示a和b的公约数个数。

样例输入:
8 16
22 16
样例输出:
    4
    2
 
 
分别求出a,b素因数的个数npa1,npa2,...,npan和npb1,npb2,...npbn,再求出来整数因数的个数(min(npa1,npb1)+1)*...*(min(npan,npbn)+1),即为a和b的公约数个数。但有一个WRONG ANSWER!
#include<stdio.h>
const int MAXN=10001;
bool p[10005];//p[i]表示i是否为素数
int npa[10005],npb[10005];
int pa[100],pb[100];
int prime()
{
    p[0]=false;
    p[1]=false;
    for (int i=2;i<=MAXN;i++)
        p[i]=true;
    for (int i=2;i<=MAXN;i++)
    {
        if (!p[i]) continue;
        for (int j=i*i;j<=MAXN;j+=i)
            p[j]=false;
    }
    return 0;
}
int min(int a,int b)
{
    return (a<b?a:b);
}
int main()
{
    prime();
    long a,b;
    while(scanf("%ld%ld",&a,&b)!=EOF)
    {
        int ca=0,cb=0;
        int num=1;
        for(int i=2;i<=MAXN;i++)
        {
            npa[i]=0;
            npb[i]=0;
        }
        for(int i=2;i<=MAXN;i++)
        {
            bool sa=false,sb=false;
            while (p[i] && a%i==0) 
            {
                npa[i]++;
                a=a/i;
                sa=true;
            }
            while (p[i] && b%i==0)
            {
                npb[i]++;
                b=b/i;
                sb=true;
            }
            if (sa && sb) num=num*(min(npa[i],npb[i])+1); 
        }
        if (a==1 && b==1) 
        {
            printf("%d\n",num);
            continue;
        }
        else if (a==b) 
        {
            num=num*2;
            printf("%d\n",num);
        }    
    }
    return 0;
}

 

 
先求出a和b的最大公约数,然后通过求素因数的个数c1,c2...cn,再求出来整数因数的个数(c1+1)*(c2+1)*...*(cn+1),即为a和b的公约数个数。
#include<stdio.h>
bool p[10000];//p[i]表示i是否为素数
int primer[3000];
int primerNum[3000];
int primerSize;
int prime_init()//素数筛法
{
    p[0]=p[1]=false;
    for (int i=2;i<=10000;i++)
        p[i]=true;
    primerSize=0;
    for (int i=2;i<=10000;i++)
    {
        if (!p[i]) continue;
        primer[primerSize++]=i;
        for (int j=i*i;j<10000;j+=i)
            p[j]=false;
    }
    return 0;
}
int main()
{
    prime_init();
    long a,b;
    while (scanf("%ld%ld",&a,&b)!=EOF)
    {
        if (a<b)
        {
            long tmp=b;
            b=a;
            a=tmp;
        }
        while(b!=0) //辗转相除法求最大公约数
        {
            long tmp=a % b;
            a=b;
            b=tmp;
        }
        int num=1;
        for (int i=0;i<primerSize;i++)
        {
            int c=0;
            while(a%primer[i]==0)
            {
                c++;
                a=a/primer[i];
            }
            num=num*(c+1);
        }
        if (a!=1) num*=2;
        printf("%d\n",num);
    }
    return 0;
}

 

 

posted on 2014-03-19 16:17  武晓伟  阅读(304)  评论(0编辑  收藏  举报