• ZOJ 2562 More Divisors(高合成数)


    ZOJ 2562 More Divisors(高合成数)

    ACM

    题目地址:ZOJ 2562 More Divisors

    题意: 
    求小于n的最大的高合成数,高合成数指一类整数,不论什么比它小的自然数的因子数目均比这个数的因子数目少。

    分析: 
    网上都叫它反素数,事实上我查了一下,翻素数应该是正着写倒着写都是素数的素数。这个应该叫高合成数,见Wikipedia: Highly composite number

    高合成数有下面特征: 
    where p1<p2<<pk are prime, and the exponents ci are positive integers. 
    Any factor of n must have the same or lesser multiplicity in each prime: 
    p1^d1×p2^d2××pk^dk0dici0<ik 
    所以用回溯枚举。

    代码

    /*
    *  Author:      illuz <iilluzen[at]gmail.com>
    *  Blog:        http://blog.csdn.net/hcbbt
    *  File:        2562.cpp
    *  Create Date: 2014-08-06 20:45:53
    *  Descripton:  Highly Composite Number
    */
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define repf(i,a,b) for(int i=(a);i<=(b);i++)
    
    typedef long long ll;
    
    const int M = 1000;
    
    ll n;
    ll bestNum;
    ll bestSum;
    ll hcm[M][2];
    ll prim[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67};  
    
    // current is num, use the prim[k], sum of divisors, the limit of prim[k] you can use
    void getNum(ll num, int k, ll sum, int limit) {
    	if (sum > bestSum) {
    		bestSum = sum;
    		bestNum = num;
    	} else if (sum == bestSum && num < bestNum) {
    		bestNum = num;
    	}
    	
    	ll p = prim[k];
    	for (int i = 1; i <= limit; i++, p *= prim[k]) {		// use i prim[k]s
    		if (num * p > n) break;
    		getNum(num *= prim[k], k + 1, sum * (i + 1), i);
    	}
    }
    
    // clac log2(n)
    int log2(ll n) {
    	int ret = 0;
    	ll p = 1;
    	while (p < n) {
    		p <<= 1;
    		ret++;
    	}
    	return ret;
    }
    
    // return the number of Highly Composite Number in [1, n]
    // and save the HCM in hcm[][2]
    int gethcm() {
    	int ret = 0;
    	n = 500000;		// [1, n]
    	while (n > 0) {
    		bestNum = 1;
    		bestSum = 1;
    		getNum(1, 0, 1, log2(n));
    		cout << bestNum << ' ' << bestSum << endl;
    
    		hcm[ret][0] = bestNum;
    		hcm[ret][1] = bestSum;
    		n = bestNum - 1;
    		ret++;
    	}
    	return ret;
    }
    
    int main() {
    	while (cin >> n) {
    		bestNum = 1;
    		bestSum = 1;
    		getNum(1, 0, 1, 50);
    		cout << bestNum << endl;
    	}
    }
    


  • 相关阅读:
    一分钟制作U盘版BT3
    微软历史最高市值是多少?
    Windows 7系统安装MySQL5.5.21图解
    cocos2d-x3.0 Physics新的物理引擎
    java使用javamail读取邮箱(收件箱为例)
    Java实现第九届蓝桥杯字母阵列
    Java实现第九届蓝桥杯字母阵列
    Java实现第九届蓝桥杯字母阵列
    Java实现第九届蓝桥杯猴子分香蕉
    Java实现第九届蓝桥杯猴子分香蕉
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4216877.html
Copyright © 2020-2023  润新知