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 }