1053: [HAOI2007]反素数ant
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3522 Solved: 2065
[ 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
HINT
Source
根据数论中的分解定理可知,一个数能分解成若干个质数的乘积,即
x=p1^a1*p2^a2*p3^a3..... 其中p1、p2、p3为x的质因数,很容易发现质数越小越好。。
然后我们可以暴力2000000000可以由前多少个质数相乘。很容易求出前10个左右就差不多超过20亿了。
之后进行爆搜,枚举每个质因数可以出现的次数即可,dfs的过程中保存最大值就好。
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<time.h>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<functional>
using namespace std;
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define maxn 1000005
#define lowbit(x) (x&-x)
#define eps 1e-9
ll a[maxn]={2,3,5,7,11,13,17,19,23,29};
ll n,ans,p;
void dfs(ll sum,int num,int cnt)
{
if(cnt>9)
return;
if(num>p)
ans=sum,p=num;
if(num==p && sum<ans)
ans=sum;
for(int i=1;i<=31;i++)
{
if(sum*a[cnt]>n)
return;
dfs(sum*a[cnt],num*(i+1),cnt+1);
sum*=a[cnt];
}
}
int main(void)
{
scanf("%lld",&n);
dfs(1ll,1,0);
printf("%lld\n",ans);
return 0;
}