ZOJ-2562 More Divisors 反素数

题意:给定一个数N,求小于等于N的所有数当中,约数最多的一个数,如果存在多个这样的数,输出其中最大的一个。

分析:反素数定义:对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数。

性质一:一个反素数的质因子必然是从2开始连续的质数。
性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....

那题题目相当于求解小于等于N中,最大的反素数。搜索即可。这个搜索的速度是很快的。

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

typedef long long LL;

LL n;
vector<int>vp;
map<int,LL>mp;

bool isprime(int x) {
    if (x < 2) return false;
    if (x == 2) return true;
    int LIM = (int)sqrt(x);
    for (int i = 2; i <= LIM; ++i) {
        if (x % i == 0) return false;
    }
    return true;
}

void pre() {
    for (int i = 2; i < 100; ++i) {
        if (isprime(i)) vp.push_back(i);
    }
}

void dfs(int p, int exp, int g, LL num) {
    if (num * vp[p] > n) {
        if (mp.count(g)) mp[g] = min(mp[g], num);
        else mp[g] = num;
        return;
    }
    num *= vp[p];
    for (int i = 1; num <= n && i <= exp; ++i, num *= vp[p]) {
        dfs(p+1, i, g*(i+1), num);
    }
}

int main() {
    pre();
    while (scanf("%lld", &n) != EOF) {
        mp.clear();
        dfs(0, 1000, 1, 1);
        printf("%lld\n", (--mp.end())->second);
        printf("size = %d\n", mp.size());
    }
    return 0;
}

 

 
posted @ 2013-09-05 20:04  沐阳  阅读(888)  评论(0编辑  收藏  举报