题目描述
定义:
设f(x)为x的约数个数
若对任意0<i<x都有f(i)<f(x),则称x为66数
给出一个正整数n,求出不大于n的最大66数
输入
给出n
输出
对应最大66数
输入样例复制
1000
输出样例复制
840
说明
40%:1<=n<=10000
100%:1<=n<=200000000
题解:
其实本题细品之后就可以变成,求小于 n 的约数个数最大的所有数中最小的那个数
补充一个小知识点:
对于一个数 n ,质因数分解后=p1C1 * …… * pnCm
约数个数为:( c1 + 1 ) * …… * ( cm + 1 )
通过这个定义可以知道,满足这个条件的数还要满足:其分解质因数中 c 数组满足递减
再看一下 n ,m 的最大取值范围-----> n 9,m 31
那就可以用搜索了
Code
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#define LL long long
#define ull unsigned LL
#define db double
#define ldb long db
#define re register
#define INF 1000000009
using namespace std;
const int N=1e6+100,M=2020;
int n,maxn,max_num,k[M]={ 0,2,3,5,7,11,13,17,19,21 };
void dfs ( int x,int ans,int num,int last )
{
if ( ans>n || x>9 ) return;
if ( ( num>max_num ) || ( num==max_num && ans<maxn ) ) maxn=ans,max_num=num;
for ( int i=1;i<=last;i++ )
{
ans*=k[x];
dfs ( x+1,ans,num*( i+1 ),i );
if ( ans>n ) return;
}
}
int main ( )
{
scanf ( "%d",&n );
dfs ( 1,1,1,31 );
printf ( "%d",maxn );
return 0;
}