51nod1060 最复杂的数

本文介绍了一种算法,用于寻找小于给定数值的最大反素数。反素数是一种特殊数,其约数数量超过所有较小的正整数。文章提供了一个具体的实现方案,包括使用深度优先搜索(DFS)和剪枝策略来高效解决问题。

题意:输入一个数n(n<1e18),找到一个数x,使得x<n,且x的约数最多

题解:满足题目条件的是反素数,网上反素数的介绍:

反素数的定义:对于任何正整数n,其约数个数记为f(n),例如f(6)=4,如果某个正整数n满足:对任意的正整数(0<i<n),都有f(i)<f(n),那么称n为反素数。
从反素数的定义中可以看出两个性质:
(1)一个反素数的所有质因子必然是从2开始的连续若干个质数,因为反素数是保证约数个数为的这个数尽量小
(2)同样的道理,如果n=2^t1*3^t2*...,那么必有t1>=t2>=t3...

所以这里可以直接dfs+剪枝

#include <bits/stdc++.h>
#define maxn 100010
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
ll prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 39, 41, 43, 47, 53, 57};
ll n, ans, ma, num;
void dfs(ll x,ll deep,ll v){
    if(x > n/prime[deep]){
        if(v > ma) ma = v, ans = x;
        else if(v == ma) ans = min(ans, x);
        return ;
    }
    ll t = prime[deep], temp = num;
    for(ll i=1;i<=temp;i++){
        if(x <= n/t){
            num = i;
            dfs(x*t, deep+1, v*(i+1));
            t *= prime[deep];
            num = temp;
        }
        else break;
    }
}
int main(){
    ll T;
    scanf("%lld", &T);
    while(T--){
        ma = 0, num = 61, ans = INF;
        scanf("%lld", &n);
        dfs(1, 0, 1);
        printf("%lld %lld\n", ans, ma);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/Noevon/p/8612905.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值