首页 > 代码库 > [SDOI2005]反素数ant

[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 }

 

[SDOI2005]反素数ant