反素数
题目链接:ybt高效进阶6-2-4
题目大意
给你一个 n,要你找一个不超过 n 的最大的数 x 使得它的约数个数比 1~x-1 的数的约数个数都多。
思路
因为是质因数分解,最多涉及
10
10
10 个质数,一个质数顶多
31
31
31 次。(而且肯定跑不满)
所以我们直接暴搜!
当然,要剪枝。
首先很显然的结果,你选的数的质因数分解肯定是从小到大连续的,因为每个质数如果选的个数相同,它的贡献是相同的。
接着我们再贪心,会发现我们选的每个质数的个数肯定是单调递减的,原因跟上面一样,那你递增的话还不如把两个质数的个数反过来,它还更小,更优。
然后注意一下如果质因数个数相同的话取的是小的那个而不是大的那个。
因为你如果选大的那个就会因为小的那个而不满足全部都小于。(不能是等于)
代码
#include<cstdio>
#define ll long long
using namespace std;
int prime[12] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
int num[12];
ll n, maxn, maxx;
void dfs(ll now, int to, ll ans) {
if (now > n) return ;
if (to > 11) return ;
if (ans > maxx || (ans == maxx && now < maxn)) {
maxx = ans;//因数更多就选,如果一样就看哪个小(大的会因为小的不符合而不行)
maxn = now;
}
for (int i = 0; i <= num[to - 1]; i++) {
num[to] = i;
dfs(now, to + 1, ans * (i + 1));
now *= prime[to];
if (now > n) return ;
}
}
int main() {
scanf("%lld", &n);
num[0] = 32;
dfs(1, 1, 1);
printf("%lld", maxn);
return 0;
}