題目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1562
題解:g(x)表示x的因子個數。
如果滿足對於任意的0<i<x,有g(i)<g(x),則稱x為反素數。
它有如下性質:
1、一個反素數的質因子一定是從2開始的連續的質數。
2、一個反素數可以唯一表示成2^a*3^b*5^c······的形式,並且a>=b>=c>=d······。
證明:(僅供參考)
先證明性質2:
因為每個整數都有唯一的因式分解,所以表示唯一。
設某個整數Y的因式分解中有t1 個2,t2個3,t3個5······
則Y的因子數為sum=(t1+1)*(t2+1)*(t3+1)······
而Y=2^t1*3^t2*5^t3······
因為要使sum最大,則需要增大t1,t2,t3······的值,而對於2的指數t1,增大的速度最大,所以a最大,其次是b,c。
有了性質2,因為a>=b>=c>=d的。所以中間不會出現0的情況。所以連續。
求n以內的數,該數的因子數最多。
就是要求n以內的最大反素數x。
證明:
在x以內,g(x)最大,在大於x小於n之間不存在因子數大於g(x)的數。
假設存在p,使g(p)>g(x),則p就是n以內的最大反素數,與x使最大反素數矛盾,顧不存在p。
n的最大值是10^16.
則最多用到14個素數來表示n。(2 3 5 7 11 13 17 19 23 29 31 37 41 43)
原始碼:
#include <stdio.h>typedef long long ll;int prime[14]={2,3,5,7,11,13,17,19,23,29,31,37,41,43};ll max,best;ll n;void getAnti_prime(ll num,int k,ll sum,int limit){ ll temp; if(sum>max) { max=sum; best=num; } if(sum==max&&best>num) best=num; if(k>=14) return; temp=num; for(int i=1;i<=limit;i++) { if(temp*prime[k]>n) break; temp=temp*prime[k]; getAnti_prime(temp,k+1,sum*(i+1),i); }}int main(){ while(scanf("%lld",&n)!=EOF) { getAnti_prime(1,0,1,50); printf("%lld\n",best); }}