1053: [HAOI2007]反素数ant
Submit: 4124 Solved: 2456
[Submit][Status][Discuss]
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的乘积
如:48=24×31
则48的因数个数为(4+1)×(1+1)=10,因此48有10个因数
分别为:1,2,3,4,6,8,12,16,24,48
证明:
我们都知道,所有的合数,都能分解为若干质数的乘积,如:48=2*2*2*2*3
而因数正是以乘积的形式联系起来的,刚好满足了我们所要求的东西
那么为什么要+1呢?
其实这里就是一个排列组合问题,还是按48来说,就是还要有20×31,2i×30(0≤i≤4),这种情况,因数还包括了1和48自身
还要在小小的理解一下题目g(x)>g(i) 0<i<x
这里就是说,当g(x)==g(i) 0<i<x,这种情况是不成立的,要取较小值i
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 5 #define LL long long 6 7 int dist[20]={2,3,5,7,11,13,17,19,23,29,31}; 8 int n,ans,num; 9 10 void dfs(LL t,int k,int tmp) 11 { 12 if(k==11) 13 { 14 if(tmp>num){ans=t;num=tmp;} 15 if(t<ans&&tmp==num){ans=t;num=tmp;} 16 return; 17 } 18 for(int i=0;i<31;i++) 19 { 20 dfs(t,k+1,tmp*(i+1)); 21 t*=dist[k]; 22 if(t>n) break; 23 } 24 } 25 26 int main() 27 { 28 scanf("%d",&n); 29 dfs(1,0,1); 30 printf("%d",ans); 31 return 0; 32 }