套路数学——蚂蚁

我也不知道为什么叫蚂蚁,,,
我也不知道原题是哪个。。。
但是既然是今天考试的题,还这么套路
就写一个博客来记录一下咯

题目:
求1-n约数个数最多的那个数
10%的数据 1

for(int i=1;i<=n;i++)
{
    if(f[i]>sum){
        sum=f[i];ans=i;
    }
    int bs=1;
    while(bs*i<n){
        bs++;
        f[i*bs]++;
    }
}

秒完之后一想,不对,数据这么大,应该打表!

然后打了一个表,试图找出其中的规律,最后放弃了
看着总觉得其中隐藏着什么不为人知的规律,可是,,,
不过同桌的frf却是天才地一个一个慢慢把答案打了出来(大概可以满分吧。。。。)

放弃了规律,忽然发现这是一道数学题
【注意,正文来了

/* 神奇的结论
int a[]=质数 ,k[]=指数
n= a[1]^k[1] * a[2]^k[2] *…..a[n]^k[n]
约数个数 t=(k[1]+1)(k[2]+1)…..*(k[n]+1)

枚举每一个质数指数 搜最大答案
转念一想,这虽然比暴力好了许多,不过大概会挂

这时我们就要有一些优化的思路:
这些思路的主旨就是在约数个数相同的情况下尽可能地让当前数小

比如:
1、第一种情况:6=2*3 10=2*5
这是一种约数不同的例子,所以我们枚举质数的时候要从小到大枚举
2、第二种情况:12=2^2*3 18=3^2*2
这时一种指数不同的例子,所以我们就可以推得较大的质数的指数一定小于较小的质数的指数

*/

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n;

int p[20]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,51};

long long maxn=-1,num=-1;
void get(long long m,int f,int t,int pr)
{//f为当前质数的编号 ,当前指数<pr
//t为当前约数的个数 
    if(t>maxn||(t==maxn&&m<num))
        num=m,maxn=t;
    int j=0,nt;
    long long i=m;
    while(j<pr)
    {
        j++;
        if(n/i<p[f])break;
        nt=t*(j+1);
        i=i*p[f];
        if(i<=n)    get(i,f+1,nt,j);
    }

}

int main()
{
    cin>>n;
    get(1,1,1,30);
    cout<<num;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GoesM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值