bzoj1053 [HAOI2007]反素数ant

Description

  对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。现在给定一个数N,你能求出不超过N的最大的反质数么?

Input

  一个数N(1<=N<=2,000,000,000)。

Output

  不超过N的最大的反质数。

Sample Input

1000

Sample Output

840

 

正解:数学+搜索。

首先我们知道,一个数的约数个数可以表示成(所有质因子的个数+1)的乘积。

然后我们又发现,$2*10^{9}$以内不会有超过$12$个质因子。

然后我们就可以搜索,注意一个剪枝,就是小质因子选取个数绝对会大于等于大质因子的选取个数,这样肯定会更优。

 

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <complex>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <cstdio>
 8 #include <vector>
 9 #include <cmath>
10 #include <queue>
11 #include <stack>
12 #include <map>
13 #include <set>
14 #define il inline
15 #define RG register
16 #define ll long long
17 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
18 
19 using namespace std;
20 
21 const ll prime[20]={1,2,3,5,7,11,13,17,19,23,29,31};
22 
23 ll n,cnt,ans;
24 
25 il void dfs(RG ll x,RG ll sum,RG ll num,RG ll last){
26     if (x==12){
27     if (cnt<num && ans<sum) cnt=num,ans=sum;
28     if (cnt<=num && ans>=sum) cnt=num,ans=sum;
29     return;
30     }
31     RG ll t=1;
32     for (RG ll i=0;i<=last;++i){
33     dfs(x+1,sum*t,num*(i+1),i);
34     t*=prime[x]; if (sum*t>n) return;
35     }
36     return;
37 }
38 
39 il void work(){
40     cin>>n; dfs(1,1,1,20);
41     printf("%lld",ans); return;
42 }
43 
44 int main(){
45     File("ant");
46     work();
47     return 0;
48 }

 

posted @ 2017-03-28 11:04  wfj_2048  阅读(163)  评论(0编辑  收藏  举报