套路数学——蚂蚁

来源:互联网 发布:sqlserver rds客户端 编辑:程序博客网 时间:2024/05/04 12:03

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

题目:
求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;}
原创粉丝点击