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,n]范围内因数最多的最小的数。
由于数经过分解可以分解成若干个质数的乘积,且形式大概是这个样子的:
n=(p1^x1)*(p2^x2)*...*(pr^xr)
其中 pi 是 n 的质因数,xi 是 pi 项的质数,
根据简单的乘法原理,n的因数个数就是(x1+1)*(x2+1)*...*(xr+1)。
又由于n<=2,000,000,000,我们只需要用到前。。。大概11个质数就可以了(大可以打个质数表验证一下)
这本身就是一个强力的剪枝。。。
所以这到底是HAOI2007还是SDOI2005????
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 6 typedef long long ll; 7 8 int n,ens=0,prime[15]={0,2,3,5,7,11,13,17,19,23,29}; 9 ll ans=0; 10 11 void dfs(int pos,ll x,ll y){ 12 if(x>ens){ ens=x; ans=y; } 13 else if(x==ens&&y<ans) ans=y; 14 if(pos>11) return; 15 for(int i=1;i<=31;i++){ 16 if(y*prime[pos]>n) break; 17 dfs(pos+1,x*(i+1),y*=prime[pos]); 18 } 19 } 20 21 int main(){ 22 scanf("%d",&n); 23 dfs(1,1,1); 24 printf("%lld\n",ans); 25 return 0; 26 }