随笔 - 13  文章 - 0  评论 - 0  阅读 - 3754 

题目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   武晓伟  阅读(307)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· 开发者新选择:用DeepSeek实现Cursor级智能编程的免费方案
· 【译】.NET 升级助手现在支持升级到集中式包管理
· 独立开发经验谈:如何通过 Docker 让潜在客户快速体验你的系统
· 并发编程 - 线程同步(二)
点击右上角即可分享
微信分享提示