来自学长的快乐AK题——Day3 D

D——简单数论

Description

定义:

设f(x)为x的约数个数

若对任意0<i<x都有f(i)<f(x),则称x为66数

给出一个正整数n,求出不大于n的最大66数

思路

(1):不同的质因子个数不会超过10,因为前10个质数的积为

2 ∗ 3 ∗ 5 ∗ 7 ∗ 11 ∗ 13 ∗ 17 ∗ 19 ∗ 23 ∗ 29 = 6 , 469 , 693 , 230 > 2 ∗ 1 0 9 2*3*5*7*11*13*17*19*23*29=6,469,693,230>2∗10^9 2357111317192329=6,469,693,230>2109

(2):质因子的个数总和不会超过31个,因为 2 31 > 2 ∗ 1 0 9 2^{31}>2*10^9 231>2109

(3):设一个数x的分解形式为 x = p 1 c 1 ∗ p 2 c 2 ∗ . . . ∗ p n c n x=p_1^{c_1}*p_2^{c_2}*...*p_n^{c_n} x=p1c1p2c2...pncn,则x的约数个数为 ( c 1 + 1 ) ∗ ( c 2 + 1 ) ∗ . . . ∗ ( c n + 1 ) (c_1+1)*(c_2+1)*...*(c_n+1) (c1+1)(c2+1)...(cn+1)。即每个质因数pi都有0~ci的指数选择。

然后我们发现,反素数其实就是 1~n 中 约数个数最多的数中最小的那个 (如果不是最小就意味着有一个比它小的数,约数个数和它一样,不符合小于的条件)。
那么我们要满足最小的原则,肯定是贪心啦。
假设我们取的质数从小到大,那么小数的数量一定要大于大数的数量,这样我们就可以满足最小了。
因为数据不大,我们使用深搜dfs搞定


转自人类高质量博客(这回扣的是大佬的啦QAQ)

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
int n,p[10]={2,3,5,7,11,13,17,19,23,29};
ll pro=1,maxn,ans;
void dfs(int k,int pre,int tot)
{
	if(k>=10) return;
	if(tot>maxn||(tot==maxn&&pro<ans))
	maxn=tot,ans=pro;
	for(int i=0;i<=pre;i++)
	{
		ll temp=pow(p[k],i);
		if(pro*temp>n) return;
		pro*=temp;
		dfs(k+1,i,tot*(i+1));
		pro/=temp;
	}
}
int main()
{
	scanf("%d",&n);
	dfs(0,30,1);
	printf("%lld",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值