Zoj 2562 More Divisors

本文介绍了一种特殊数——反素数的概念及其性质,并提供了一个基于这些性质的算法实现,用以找出小于给定数值的最大反素数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:给定一个数n,求在n以内,一个数的约数最多,并且是最小的一个数。

分析:先把约数看成素因子了,导致算法和思路严重错误。

约数和素因子是不同的。比如12=2^2*3,它的素因子数为2,而约数为6,分别为:1,2,3,4,6,12.

不过,可以总结出约数的个数等于每个数的素因子的幂加1相乘。12=2^2*3.  m=(2+1)*(1+1)=3;

其实此题是一个关于反素数的问题,有关反素数:网上有这样的说明:

定义

对于任何正整数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>=....
载自百度.....!
根据分析:题目只有10^16,故素因子越小的会成为最佳结果,故大楷只要15素数就可以了。
#include<cstdio>
#include<cstring>
typedef long long LL;
using namespace std ;
LL Max,best,n;
int prime[15]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
void dfs(LL sum,LL cur,int k,int t)
{
	if(Max<sum){
	 Max=sum;
	 best=cur;
	}
	if(sum==Max&&cur<best) best=cur;
	if(k>14) return;
	LL tmp=cur;
	for(int i=1;i<=t;i++){
		if(tmp*prime[k]>n) break;
		tmp*=prime[k];
		dfs(sum*(i+1),tmp,k+1,i);
	}	
}
int main()
{
   while(scanf("%lld",&n)!=EOF){
	  Max=best=1;
	  dfs(1,1,0,50);
	  printf("%lld\n",best);	
   }
 	return 0 ;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值