欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

1053: [HAOI2007]反素数ant

程序员文章站 2022-04-12 12:25:51
Description 对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。如果某个正整数x满足:g(x)>g(i) 0
Time Limit: 10 Sec  Memory Limit: 162 MB
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 }