zoukankan      html  css  js  c++  java
  • 数论专题第三题 :C

    可能还是太菜了,最近每写一道题都会显得十分吃力,不过令人欣慰的是还可以从中学到不少的东西。

    题目的大概意思:给出面积啊a,还有最短的边b,求出能够组成矩形一共有多少个组合。
    samole input:

    10 2
    12 2
    sample output:

    1       (10一共有两对因数,2,5还有1,10);

    2

    分析:题目的意思很明显就是要求出a的符合条件的因数的对数找出来,那么涉及到数的因数,就应该想到“算术基本定理”,而算法基本定理又要有素数作为铺垫,所以筛选素数又要用到”欧拉函数筛选法“

    思路:先用“算术基本定理”算出a总体一共有多少个因数,在除以2来求对数,之后暴力求出1到b有多少限制的对数,两者相减便是答案。

    注意事项:由于a给出的范围是10的12次方,所以素数筛选只需要筛选到10的6次方就可以了(m*m=a,过了m之后便会重复)。

    第二个注意的地方也是题目最为关键的地方之一:代码如下:

    if(a/b < b)      //意思就是当b的限制达到a的算术平方根的时候,那么将不会在存在任何一个满足题目的组合,那么就可以直接输出结果,并且continue循环执行下一个;
            {
               printf("Case %d: %lld
    ",i,0);
                continue;
            }

    总体的代码走一走:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define Max 1000005
    #include<cmath>
    using namespace std;
    
    typedef long long int ll;
    bool vis[Max];
    int p[Max],p_num=0;
    void ola()
    {
        memset(vis,false,sizeof(vis));
        memset(p,0,sizeof(p));
        for(int i=2;i<Max;i++)
        {
            if(!vis[i])
                p[p_num++]=i;
            for(int j=0;j<p_num;j++)
            {
                if(i*p[j]>Max)
                    break;
                vis[i*p[j]]=true;
                if(i%p[j]==0)
                    break;
            }
        }
    }
    
    ll Ans(ll n)
    {
        ll sum =1;
        for(int i=0;i<p_num && p[i]<=n;i++)
        {
            if(n%p[i]==0)
            {
                int cnt=0;
                while(n%p[i]==0)
                {
                    n=n/p[i];
                    cnt++;
                }
                sum=sum*(cnt+1);
            }
        }
        if(n>1)
            sum=sum*2;
        return sum;
    }
    
    int main()
    {
        ola();
        int T;
        ll a,b;
        scanf("%d",&T);
        for(int i=1;i<=T;i++)
        {
            scanf("%lld %lld",&a,&b);
    
            if(a/b < b)
            {
               printf("Case %d: %lld
    ",i,0);
                continue;
            }
            ll cnt = Ans(a)/2;
            for(int j=1;j<b;j++)
            {
                if(a%j==0)
                {
                    cnt--;
                }
            }
            printf("Case %d: %lld
    ",i,cnt);
        }
    
        return 0;
    }
  • 相关阅读:
    鸟哥的Linux私房菜基础学习篇(第三版)——阅读笔记(二)
    鸟哥的Linux私房菜基础学习篇(第三版)——阅读笔记(一)
    Git的使用流程及常用命令汇总
    Protocol buffers编写风格指南
    Effective Go中文版(更新中)
    go package 学习笔记 —— strconv(string与其他基本数据类型(int, float, bool)的转换)
    在iis上部署 AngularJS
    asp.net Core 2.0部署到iis上
    ABP 运行前端代码
    Asp.NET Core2.0 EF ABP Postgresql 数据迁移
  • 原文地址:https://www.cnblogs.com/myxdashuaige/p/8968869.html
Copyright © 2011-2022 走看看