ZOJ 2562 反素数

在讲解反素数之前,我们先来看反素数的概念。

反素数的定义:对于任何正整数,其约数个数记为,例如,如果某个正整数满足:对任意的正整

,都有,那么称为反素数。

从反素数的定义中可以看出两个性质:

(1)一个反素数的所有质因子必然是从2开始的连续若干个质数,因为反素数是保证约数个数为的这个数尽量小

(2)同样的道理,如果,那么必有

在ACM竞赛中,最常见的问题如下:

(1)给定一个数,求一个最小的正整数,使得的约数个数为

(2)求出中约数个数最多的这个数

从上面的性质中可以看出,我们要求最小的,它的约数个数为,那么可以利用搜索来解。

以前我们求一个数的所有因子也是用搜索,比如,以每一个为树的一层建立搜索树,深度为

为例进行说明,建树如下:

再看一道例题:

题意:给一个数,求一个最小的正整数,使得它的因子个数为

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
typedef unsigned long long ULL;
const ULL INF = ~0ULL;

int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};

int n;
ULL ans;

void dfs(int dept,ULL tmp,int num)
{
    if(num > n) return;
    if(num == n && ans > tmp) ans = tmp;
    for(int i=1;i<=63;i++)
    {
        if(ans / p[dept] < tmp) break;
        dfs(dept+1,tmp *= p[dept],num*(i+1));
    }
}

int main()
{
    while(cin>>n)
    {
        ans = INF;
        dfs(0,1,1);
        cout<<ans<<endl;
    }
    return 0;
}

  -------------以上转自http://blog.csdn.net/ACdreamers/article/details/25049767----------

我自己想说一下对例题代码的理解

代码主要部分是

int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};

int n;
ULL ans;

void dfs(int dept,ULL tmp,int num) //其实此处DFS即是枚举。i的次数递增,即是对应
                         //p[dept]的指数的增加。深度dept即是第几个素数。63次方已是
                        //足够大了。枚举指数来看其约数的个数。
{
    if(num > n) return;
    if(num == n && ans > tmp) ans = tmp;
    for(int i=1;i<=63;i++)
    {
        if(ans / p[dept] < tmp) break;
        dfs(dept+1,tmp *= p[dept],num*(i+1));
    }
}

int main()
{
    while(cin>>n)
    {
        ..................
        dfs(0,1,1);
        .................
    }
    return 0;
}

  

ZOJ 2562

紧接着,我自己就做了这一题

#include <iostream>
#include <cstdio>
#include <algorithm>
#define LL long long

using namespace std;
LL p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
LL ans,n,c;

void solve(int dep,LL tmp, LL num){
	if(tmp>n) return ;
	if(num>c||(num==c)&&tmp<ans){
		ans=tmp;
		c=num;
	}
	for(LL i=1;i<=60;i++){
		if(tmp*p[dep]>n) break;
		solve(dep+1,tmp*p[dep],num*(i+1));
		tmp*=p[dep];
	}
}

int main(){
	while(scanf("%lld",&n)!=EOF){
		c=0;
		ans=(1<<60);
		solve(0,1,1);
		printf("%lld\n",ans);
	}
	return 0;
}

  

时间: 2024-12-25 08:42:03

ZOJ 2562 反素数的相关文章

zoj 2526 反素数 附上个人对反素数性质的证明

反素数的定义:对于任何正整数,其约数个数记为,例如,如果某个正整数满足:对任意的正整 数,都有,那么称为反素数. 从反素数的定义中可以看出两个性质: (1)一个反素数的所有质因子必然是从2开始的连续若干个质数,因为反素数是保证约数个数为的这个数尽量小 (2)同样的道理,如果,那么必有 个人理解性证明: 对(1)假设不是从2开始,那么假设n的最小素因素是k,把k换成2,2的次数仍等于k的次数,得到N,可知,N<n,并且f(n)==f(N),与n是反素数矛盾 对(2)假设ti<tj   ti,tj

zoj 1562 反素数 附上个人对反素数性质的证明

反素数的定义:对于不论什么正整数,其约数个数记为.比如,假设某个正整数满足:对随意的正整 数.都有,那么称为反素数. 从反素数的定义中能够看出两个性质: (1)一个反素数的全部质因子必定是从2開始的连续若干个质数.由于反素数是保证约数个数为的这个数尽量小 (2)相同的道理,假设,那么必有 个人理解性证明: 对(1)如果不是从2開始,那么如果n的最小素因素是k,把k换成2,2的次数仍等于k的次数,得到N,可知,N<n,而且f(n)==f(N).与n是反素数矛盾 对(2)如果ti<tj   ti,

ZOJ 2562 HDU 4228 反素数

反素数: 对于任何正整数x,起约数的个数记做g(x).例如g(1)=1,g(6)=4. 如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数. ZOJ 2562 反素数 因为写了POJ 2886的线段树,然后里面有反素数,以前没遇到过,所以先搞这两题普及一下知识再说. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm&

ZOJ 1562 More Divisors 反素数

最裸的反素数问题.求不大于N的数约数最多的数是多少,如果有多个求最小值. 设x的约数个数为g(x),如果有某个正整数a有对于任意0<i<a有g(i)<g(a),则称a为反素数. g(x)的计算方法,先分解质因子x=a^b*c^d*e^f- g(x)=(b+1)*(d+1)*(f+1),即指数+1的乘积 反素数有性质: 一个反素数的质因子必然是从2开始的连续质数 2^t1*3^t2*5^t3*7^t4.....必然有t1>=t2>=t3>=.... 有了这些性质之后,就可

ZOJ 2562 More Divisors(高合成数)

ZOJ 2562 More Divisors(高合成数) ACM 题目地址:ZOJ 2562 More Divisors 题意: 求小于n的最大的高合成数,高合成数指一类整数,不论什么比它小的自然数的因子数目均比这个数的因子数目少. 分析: 网上都叫它反素数,事实上我查了一下,翻素数应该是正着写倒着写都是素数的素数.这个应该叫高合成数,见Wikipedia: Highly composite number 高合成数有下面特征: where p1<p2<?<pk are prime, an

zoj 2562

典型的反素数 对于任何正整数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>=.... #include <iostream>using namespace std; typedef long long ll; int

poj 2886 线段树的更新+反素数

Who Gets the Most Candies? Time Limit: 5000 MS Memory Limit: 0 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description N children are sitting in a circle to play a game. The children are numbered from

反素数 -- 数学

反素数就是区间内约数个数最多的那个数. 在ACM题目里, 一般是求约数最多而且数字最小的那个数,[1--n] 二是求约数刚好等于n的最小的那个数 三是求区间里的最小反素数[beign,end] 1和3有区别吗?有,1可以加速,3只能暴力 先说下思路 思路 : 官方题解 : (1)此题最容易想到的是穷举,但是肯定超时. (2)我们可以知道,计算约数的个数和质因数分解有着很大的联系: 若Q的质因数分解为:Q=p1^k1*p2^k2*…*pm^km(p1…pm为素数,k1…km≥1),则Q有(k1+1

反素数(暴力)

反素数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5194    Accepted Submission(s): 3043 Problem Description 反素数就是满足对于任意i(0<i<x),都有g(i)<g(x),(g(x)是x的因子个数),则x为一个反素数.现在给你一个整数区间[a,b],请你求出该区间的x