题意:
对于任何正整数 x ,其约数的个数记为 g(x)。如果某个正整数 x 满足:
对于任意的 0 < i < x,都有g(x) > g(i),那么x为反质数。例如整数 1,2,4,6
等都是反质数。先给定一个数 N,求出不超过 N 的最大的反质数。
N <= 2e9.
样例输入:
1000
样例输出:
840
思路:
本题第一个思维跳跃之处在于将原问题转换为找1~N中因子数目最多的数x,
对于转换后的问题,采用暴力1~N诸葛判断显然不可以,所以采用了通过质因子
公式来求约数个数的方法暴搜所有可行解,并根据性质进行剪枝。
1.若x为1~N中最大的反素数,则x为1~N中约数最多的最小的数。
2.int范围内的数的不同质因子种类数不会超过10个,becaues 235…23即将超出int范围.
3.int范围内所有数的质因子的指数和小于等于30.
4.x的质因子一定由最小的几个连续的质数构成,且质因子的次数单调递减.综上有思路:
从前往后,暴搜每个质因子的个数.(满足条件2.3.4),构造最优解并记录作为答案.
代码实现:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
int n;
int sum, minx;
int ps[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
void sol (int x, int last, int s, int p) {
if (s > sum || s == sum && p <= minx) {
sum = s;
minx = p;
}
for (int i = 1; i <= last; i ++ ) {
if ((LL) p * ps[x] > n) break; // 边界不用特殊处理,会直接break然后return.
p = p * ps[x];
sol (x + 1, i, s * (i + 1), p);
}
}
int main () {
sum = 0;
cin >> n;
sol (0, 30, 1, 1);
cout << minx << endl;
return 0;
}
THE END;