杭电 ACM Step Chapter Two Section 1

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qinlingheshang/article/details/80635799

最小公倍数

这里写图片描述

  • 两个数的最小公倍数=两个数的乘积/两个数的最大公约数,即[a,b]=a*b/(a,b)。问题转化成求最大公约数,这里使用欧几里得辗转相除法求解。
#include <stdio.h>
#include <stdlib.h>
int gcd(int a,int b)//求两个正整数的最大公约数
{
    int r,t;
    if(a<b) //保证a>b
    {
        t=a;
        a=b;
        b=t;
    }
    while(a%b !=0)
    {
        r=a%b;
        a=b;
        b=r;
    }
    return b;
}
int main()
{
    int a,b;
    int lcm,g;
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        g=gcd(a,b);
        lcm=(a*b)/g;
        printf("%d\n",lcm);
    }
    return 0;
}

How many prime numbers

这里写图片描述

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int IsPrime(int a)
{
    if(a<2) return 0;//小于2的数既不是素数也不是合数
    for(int i=2;i<=sqrt(a);i++)
    {
        if(a%i==0) return -1;//能够整除非1的某个数,说明是合数
    }
    return 1;//判断为素数,返回1
}
int main()
{
    int N;/*将输入数据的个数*/
    int a,sum;
    while(scanf("%d",&N)!=EOF)
    {
        sum=0;
        while(N--)
        {
            scanf("%d",&a);
            if(IsPrime(a)==1) sum++;
        }
        printf("%d\n",sum);
    }
    return 0;
}

相遇周期

这里写图片描述

  • 这道题中的相遇周期即两个卫星各自周期的最小公倍数。所以问题转化为求分数的最小公倍数问题。
  • 解法:首先将分数化为最简形式,然后求分子的最小公倍数作为分子,分母的最大公约数作为分母
  • 注意点:数据类型有问题,刚开始写好代码却报错,上网借鉴别人的代码,发现数据类型不是简单的int型,输入中给出的那一串\\\符号已经表明数字会很大,所以需要使用更长的数据类型。
#include <stdio.h>
__int64 _gcd(__int64  x,__int64  y)
{
    __int64  r;
    if(x<y)
    {
        __int64  temp=y;
        y=x;
        x=temp;
    }
    while(x%y !=0)
    {
        r=x%y;
        x=y;
        y=r;
    }
    return y;
}
__int64  main()
{
    __int64  T;
    __int64  a,b,c,d;
    scanf("%I64d",&T);
    __int64  m,n;
    while(T--)
    {
        scanf("%I64d/%I64d%I64d/%I64d",&a,&b,&c,&d);
        /*首先将分数化为最简形式*/
        m=_gcd(a,b);
        a=a/m;
        b=b/m;
        n=_gcd(c,d);
        c=c/n;
        d=d/n;

        m=_gcd(b,d);//对分母求最大公约数
        n=_gcd(a,c);
        n=(a*c)/n;//对分子求最小公倍数
        if(n%m==0) printf("%I64d\n",n/m);
        else printf("%I64d/%I64d\n",n,m);
    }
    return 0;
}

Largest prime factor

这里写图片描述

  • 初始的思路是将范围内所有的素数找出并保存到数组A中,然后对输入的数据在A中寻找其最大素因子,其下标即所在位置,但是提交发现超时
  • 后来借鉴网上思路,利用素数筛选法的思路解决问题
#include <stdio.h>
#include <math.h>
#define max 1000001
int LPF[max];/*注意非静态变量数组不能开的太大*/
int main()
{
    for(int i=0;i<max;i++) LPF[i]=0;
    int n,postion=0;//positon表示某个素数在素数表中的位置
    LPF[1]=0;
    for(int i=2;i<max;i++)
    {
        if(LPF[i]==0) //如果i还未被小于自身的任何素数整除,则确定i也是素数
        {
            postion++;
            for(int j=i;j<max;j=j+i) LPF[j]=postion;
            //所有是i的倍数的整数,LPF的值暂时为positon,不管更新,即得到最大素因子的位置
        }
    }
    while(scanf("%d",&n) != EOF)
    {
        printf("%d\n", LPF[n]);
    }
    return 0;
}

又见GCD

这里写图片描述

#include <stdio.h>
int _gcd(int x,int y)
{
    if(x<y)
    {
        int temp=y;
        y=x;
        x=temp;
    }
    int r=y;
    while(x%y)
    {
        r=x%y;
        x=y;
        y=r;
    }
    return r;
}
int main()
{
    int n;
    int a,b,c;
    scanf("%d",&n);
    int max=10;
    for(int i=2;i<7;i++) max=max*10;
    while(n--)
    {
        scanf("%d%d",&a,&b);
        c=2*b;
        for(int i=3;c<max;i++)
        {
            if(_gcd(a,c)==b)
            {
                printf("%d\n",c);
                break;
            }
            c=i*b;
        }
    }
    return 0;
}

七夕节

这里写图片描述
这里写图片描述

#include <stdio.h>
int main()
{
    int A[500005];
    A[1]=0;
    for(int i=2;i<500001;i++) A[i]=1;//大于1的数都有因子1
    for(int i=2;i<500001;i++) 
    {
        for(int j=2*i;j<500001;)
        {
            A[j]=A[j]+i;//记录数j的因子和
            j=j+i;
        }
    }
    int T,N;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);
        printf("%d\n",A[N]);
    }
    return 0;
}

找新朋友

这里写图片描述

  • 欧拉函数:对于正整数n,欧拉函数就是小于或者等于n的数中与n互质的数的数目
  • 通过百度可以得到欧拉函数的通式。根据通式编写代码。
#include <stdio.h>
#define max 32768
int A[max];
void eular()
{
    A[1]=1;
    for(int i=2;i<max;i++) A[i]=i;
    for(int i=2;i<max;i++)
    {
        if(A[i]==i)
        {
            for(int j=i;j<max;j=j+i)
                A[j]=A[j]/i*(i-1);//欧拉通式
        }
    }
}
int main()
{
    int CN,N;
    eular();
    scanf("%d",&CN);
    while(CN--)
    {
        scanf("%d",&N);
        printf("%d\n",A[N]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qinlingheshang/article/details/80635799