牛客练习赛14 A-n的约数(详解)

链接: https://www.nowcoder.com/acm/contest/82/A
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

t次询问,每次给你一个数n,求在[1,n]内约数个数最多的数的约数个数

输入描述:

第一行一个正整数t
之后t行,每行一个正整数n

输出描述:

输出t行,每行一个整数,表示答案

分析:

1)约数个数定理:

对于一个大于1的正整数n可以分解质因数: 

则n的正约数个数是:

p1,p2,p3……是质数

2)对于12=2^2*3,18=2*3^2,可见约数个数相同的数,质数的指数大的约靠前,我们越能得到较小的数,所以给指数一个上限,(根据题目2^q不超过最大n值即可),让下一个素数的指数小于这个素数的指数。

3)代码中的num表示1-n中约数最多的数。

if(t>maxn||(t==maxn&&m<num)){
        num=m;
        maxn=t;
    }

t表示当前数的约数个数,maxn表示最大的约数个数,m表示的是当前的数,可见,当t>max时或等于且m<num值时,我们另num=m,maxn=t;也就是说当约数个数相同的时候,我们求的是较小的那个数(当然这道题没让求num)

代码如下:

#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
int a[20]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,51};
ll n,num,maxn;//maxn表示1-n内最大的约数个数,num表示最大约数的数


void dfs(ll m,ll f,ll t,ll pr){//m当前值,f当前素数,t约数个数,pr质数限制
    if(t>maxn||(t==maxn&&m<num)){
        num=m;
        maxn=t;
    }
    ll z=1,yg,now=m;//z当前素数的指数,yg约数个数,now记录当前值的变化
    while(z<=pr){
        z++;
        if(n/a[f]<now){//这种情况不能再乘p[f]这个素数了
            break;
        }
        yg=t*z;//约数的个数=当前约数的个数*素数的指数加1(z每次都先+1了)
        now=now*a[f];
        dfs(now,f+1,yg,z-1);//下一个素数的指数要小于这个素数的指数所以z-1
    }
}


int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        num=-1,maxn=-1;
        scanf("%lld",&n);
        dfs(1,1,1,64);
        printf("%lld\n",maxn);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值