[BZOJ]1053 [HAOI2007]反素数ant (因数个数分析+DFS搜索)

来源:互联网 发布:红蜘蛛软件怎么卸载 编辑:程序博客网 时间:2024/05/17 01:06

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1053


题目大意:对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。现在给定一个数N,求不超过N的最大反质数

数据范围:1 <= N <= 2,000,000,000

题目解答:因数个数分析+DFS搜索(复杂度:O(不大于N的反质数的因数个数*logN)  不算很高)

        要找不大于N的最大反质数就是要找不大于N的因数最多的数K,由于2*3*5*7*....*23*29已经超过N的范围,所以只需要暴力搜索这10个质数的个数构成的不超过N的且因数个数最多的数即可。


#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;const int maxn = 100;ll prime[11] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29};ll n;ll ans = 1, num = 1;///k是当前枚举第k个质因子,now是当前得到的数,cnt是因子个数,t是枚举当前质因子的个数void dfs(int k, ll now, ll cnt, int t){    if(k >= 10)    {        if(now > ans && cnt > num)        {            ans = now, num = cnt;        }        if(now < ans && cnt >= num)        {            ans = now, num = cnt;        }        ///由于是不同质因子构成的数所以不存在now == ans的情况        return;    }    ll tmp = 1;    for(int i = 0; i <= t; ++i)    {        dfs(k+1, now*tmp, cnt*(i+1), i);         ///如果大的质因子个数多于小质因子个数必然不是最优        ///所以后一个因子个数最多与前一个因子个数相同为i        tmp *= prime[k];        if(now*tmp > n) break;    }}int main(){    while(scanf("%lld", &n) != EOF)    {        dfs(1, 1, 1, 20);        printf("%lld", ans);    }    return 0;}




0 0
原创粉丝点击