[SDOI2005]反素数ant
题目描述
对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。
如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。
现在给定一个数N,你能求出不超过N的最大的反质数么?
输入输出格式
输入格式:一个数N(1<=N<=2,000,000,000)。
输出格式:不超过N的最大的反质数。
输入输出样例
输入样例#1:
1000
输出样例#1:
840
根据整数的唯一分解定理,每个反素数都可以分解为2^i1*3^i2*5^i3*... 因数个数为(i1+1)*(i2+1)*...
搜索每个素数用几个,然后每一步都判一下这个数是不是反素数,若当前这个数的因数比已知最大的反素数的因数多,那么就更新反素数,若因数相等,则要取小的那个.
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<algorithm> 7 #include<map> 8 #include<complex> 9 #include<queue> 10 #include<stack> 11 #include<cmath> 12 #include<set> 13 #include<vector> 14 #define LL long long 15 using namespace std; 16 LL n,maxg=1,ans; 17 int prime[13]={2,3,5,7,11,13,17,19,23,29,31,37,41}; 18 void search(LL x,LL g,LL now){ 19 if(g>maxg) maxg=g,ans=now; 20 else if(g==maxg) ans=min(ans,now); 21 if(x==13) return; 22 LL k=1; 23 for(int i=0;;i++){ 24 if((now*k)>n) break; 25 search(x+1,g*(i+1),now*k); 26 k*=prime[x]; 27 } 28 } 29 int main(){ 30 freopen("!.in","r",stdin); 31 freopen("!.out","w",stdout); 32 scanf("%lld",&n); 33 search(0,1,1); 34 printf("%lld",ans); 35 return 0; 36 }