http://acm.zju.edu.cn/onlinejudge/showProblem.do?
problemId=1562
题意:求小于等于n(1 <= n <= 1016)的约数个数最多的数。
依据反素数的定义,这个题就是让求最大的反素数。
反素数搜索的根据的两个重要的性质:
反素数的质因子是从2開始的连续的素数。
p=2^t1*3^t2*5^t3*7^t4.....必定t1>=t2>=t3>=....
另外一个性质:对于p=2^t1*3^t2*5^t3*7^t4.....。p的因子的个数为(t1+1)*(t2+1)......*(tn+1)。
由于n最大是10^16,因此t最大能够为54,依据以上性质枚举每个素数以及每个素数的个数进行搜索。
#include <stdio.h> #include <iostream> #include <map> #include <set> #include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #include <algorithm> #define LL long long #define _LL __int64 #define eps 1e-12 #define PI acos(-1.0) using namespace std; LL n; int prime[20] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59}; LL Maxcur; //当前最大的反素数 int Maxcnt;//最大反素数相应的因子个数 void get_antiprime(LL cur, int cnt, int Maxnum, int k) { if(cur > n) return; if(cnt > Maxcnt) { Maxcnt = cnt; Maxcur = cur; } if(cnt == Maxcnt && cur < Maxcur) { Maxcur = cur; } LL tmp = cur; //枚举第K个素数的个数 for(int i = 1; i <= Maxnum; i++) { tmp *= prime[k]; if(tmp > n) return; get_antiprime(tmp,cnt*(i+1),i,k+1); } } int main() { while(~scanf("%lld",&n)) { Maxcur = 1; Maxcnt = 1; get_antiprime(1,1,54,0); printf("%lld ",Maxcur); } return 0; }
版权声明:本文博客原创文章,博客,未经同意,不得转载。