题意: 求出 n 以内的最大反素数。
分析: 如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数.
求[1..N]中最大的反素数–>求约数最多的数
如果求约数的个数 756=2^2*3^3*7^1
(2+1)*(3+1)*(1+1)=24
基于上述结论,给出算法: 按照质因数大小递增顺序搜索每一个质因子,枚举每一个质因子
剪枝:
性质一: 一个反素数的质因子必然是从2开始连续的质数.
因为最多只需要10个素数构造:2,3,5,7,11,13,17,19,23,29
性质二:p=2^t1*3^t2*5^t3*7^t4…..必然t1>=t2>=t3>=….
#include <stdio.h> #include <string.h> #include <math.h> typedef __int64 INT; INT rsum; // 约数的个数 INT rnum; // 约数最多的数 INT n; // n 以内的最大反素数 // 事先估算 2*3*..p>n INT pri[22] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}; // 走到 num 这个数,用到了第 k 个素数,num的约数的个数为sum void getnum(INT num,INT sum,INT k,INT lim) { if(num > n) return; if(sum > rsum){ rsum = sum; rnum = num; } else if(sum == rsum && num < rnum){ rnum = num; // 取相同约数的最小值 } INT i, p = 1; for(i = 1; i <=lim; i++){ p*=pri[k]; if(num*p>n) break; getnum(num*p,sum*(i+1),k+1,i); } } INT log2(INT n) // 求大于等于log2(n)的最小整数 { INT i = 0; INT p = 1; while(p<n){ p*=2; i++; } return i; } int main() { int ca=1,t; scanf("%d",&t); while(t--) { scanf("%I64d",&n); rsum = rnum =0; getnum(1,1,0,log2(n)); printf("Case #%d: %I64d\n",ca++,rnum); } return 0; }