51nod1060 最复杂的数

题意:输入一个数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;
}

 

posted on 2018-03-20 21:43  2855669158  阅读(143)  评论(0编辑  收藏  举报

导航