bzoj 1053 反素数
题目大意:定义,当任意小于x的数的约数的个数都小于x的约数的个数时,称x为反素数。
给定n <= 2e9,求小于等于n的最大的反素数。
感觉以前刷数学刷偏了。这么简单的题都不会。。。
显然,当两个小于等于n的数的因子数相同时,较小的那个数才是反素数(之前就是这里没发现)。而因子数等于这个数的质因数展开式的各个幂+1之积,所以显然质因数越小越好,因为越小幂就会越大,而且越小这个数的值也越小。所以我们暴力枚举前10个素数的幂(用dfs剪一下枝),然后取因子数最大时的最小值即可。
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
int n;
const int len = 10;
const int ps[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
int mx, x;
void dfs(int d, int now, int num) {
if (len == d) {
if (num > mx) {
mx = num;
x = now;
} else if (num == mx) {
x = min(x, now);
}
} else {
for (int cnt = 0; ; ++cnt) {
dfs(d + 1, now, num * (cnt + 1));
LL tmp = (LL)now * ps[d];
if (tmp > n) break;
else now = tmp;
}
}
}
int main() {
scanf("%d", &n);
mx = x = -1;
dfs(0, 1, 1);
printf("%d", x);
return 0;
}