Acwing 198 反素数

题意:

对$x$,其约数个数记作$g(x)$,若某个数$x$满足对于任意小于$x$的数$i$都有$g(x) > g(i)$,则称$x$为反素数。给定一个$n$,求不超过$n$的最大的反素数

思路:

求约数个数最多的数中最小的数,由唯一分解定理,可推出:

1、不同的质因子数量不会太多 $2 × 3 × 5 × 7 × 11 × 13 × 17 × 19 × 23 × 29 = 6469693230 > 6 × 10^9$,最多只会包括9个

2、每个质因子的次数最大是30 ($2^{30} > 10^9$)

3、所有质因子的次数一定递减 (结合约数个数公式)

暴搜就好

Code:

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <time.h>
#include <cstring>
#include <iostream>
#include <stdlib.h>
#include <algorithm>

using namespace std;

typedef long long ll;

const int N = 1e5 + 20;
const int M = 1e5 + 20;
const int mod = 1e9 + 7;

int n, m;
int ans = 0, mid = 0;
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};

void dfs(int cnt, int k, int res, int maxd){
    if(cnt == 10) return;
    if(maxd > mid || maxd == mid && ans > res) mid = maxd, ans = res;

    int p = 1;
    for(int i = 1; i <= k; i ++){
        p *= primes[cnt];
        if((ll)res * p > n){
            break;
        }
        dfs(cnt + 1, i, res * p, maxd * (i + 1));
    }

}

void solve()
{
    cin >> n;
    dfs(0, 30, 1, 1);
    cout << ans << "
";
    
}

int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("/home/jungu/code/in.txt", "r", stdin);
#endif
    cout.tie(0);

    int T = 1;
    // R(T);
    while (T--)
    {
        solve();
    }
    // W(time);

    return 0;
}
原文地址:https://www.cnblogs.com/jungu/p/13411824.html