[TOC]
题意
对于任何正整数 x,其约数的个数记作 g(x),例如 g(1)=1、g(6)=4。如果某个正整数 x 满足:对于任意的小于 x 的正整数 i,都有 g(x)>g(i),则称 x 为反素数。
例如,整数 1,2,4,6等都是反素数。
现在给定一个数 N,请求出不超过N的最大的反素数。(
N
≤
2
9
N \le 2^9
N≤29)
思路
其实最大的反素数的另一个含义就是,约数个数最多并且值最小的数就是我们要求的答案。
根据整数分解定理
N
=
A
1
a
1
∗
A
2
a
2
∗
A
3
a
3
∗
.
.
.
∗
A
n
a
n
N = A_1^{a_1}*A_2^{a_2}*A_3^{a_3}*...*A_n^{a_n}
N=A1a1∗A2a2∗A3a3∗...∗Anan
那么我们要求的是值越小越好那么就是越小的质因子个数越多越好,如果答案乘上
A
3
A_3
A3肯定不如乘上
A
1
A_1
A1的小,并且
A
1
a
1
+
1
,
A
3
a
3
−
1
A_1^{a_1+1}, A_3^{a_3-1}
A1a1+1,A3a3−1并不影响约数的个数。
前9个质数的乘积已经大于
2
9
2^9
29,因此我们可以采用DFS的方法,从最小的一个质数枚举,每个质数的个数由大到小,并且一个数的个数不超过30因为
2
31
>
2
9
2^{31} > 2^9
231>29,求出约数个数最多并且值最小的数。
代码
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define int long long
#define endl "\n"
#define xx first
#define yy secod
using namespace std;
typedef pair<int, int> PII;
const int N = 1e6 + 10, mod = 1e9+7;
int n, m, k, _, cnt;
int arr[N];
int num;
int ma;
int p[N] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
void dfs(int u, int last, int px, int s) // 第几个质数开始,有多少个当前质数,前面所有数的乘积,约数个数
{
if(s > ma || s == ma && px < num)
{
ma = s;
num = px;
}
if(u == 9) return;
for(int i = 1; i <= last; i ++)
{
if(px*p[u] > n) break;
px *= p[u];
dfs(u+1, i, px, s*(i+1));
}
}
signed main()
{
IOS;
cin >> n;
dfs(0, 30, 1, 1);
cout << num << endl;
return 0;
}