1053: [HAOI2007]反素数ant
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2421 Solved: 1344
[ 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之积。
那么首先明确一点,在生成一个数时,想要他的约数个数最大,那个就要让素因数的个数最大化,同时可以发现,小素数越多越占优,及大素数的个数不得大于任何一个小素数,原因在于假如有2个7,一个5,那么也可以有2个5一个7,且一定比之前的大,那么就不符合要求了。
于是由此发现,最多有12个数(1,2,3,5,7,11,13,17,19,23,29,31)(之积已经大于2000000000)
接下来就是爆搜了
code:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define ll long long
using namespace std;
ll prime[]={1,2,3,5,7,11,13,17,19,23,29,31};
ll n,ans=1;int num=1;
void dfs(int k,ll now,int cnt,int last){
if(k==12){
if(now>ans&&cnt>num){ans=now,num=cnt;}
if(now<ans&&cnt>=num){ans=now,num=cnt;}
return ;
}
ll x=1;
for(int i=0;i<=last;i++){
dfs(k+1,now*x,cnt*(i+1),i);
x*=prime[k];
if(now*x>n)return;
}
}
int main()
{
cin>>n;
dfs(1,1,1,40);
cout<<ans;
return 0;
}