[POI2001][HAOI2007]反素数【数论】【DFS】

>Link

luogu P1463


>Description

在这里插入图片描述
1 ≤ n ≤ 1 0 9 1≤n≤10^9 1n109


>解题思路

题目大意:求在 [ 1 , n ] [1,n] [1,n]内的一个数,这个数的约数最多且尽可能小

我们知道 x x x可以表示为 x = ∏ p i k i x=\prod p_i^{k_i} x=piki p i p_i pi都为质数
x x x的约数个数为 g ( x ) = ∏ ( k i + 1 ) g(x)=\prod (k_i+1) g(x)=(ki+1)

对于所有的 p i p_i pi k i k_i ki可以为0),观察一下发现,如果有 k i < k j k_i<k_j ki<kj,并且 p i < p j p_i<p_j pi<pj,那为了使得最终乘起来的数尽可能小,更优的是使得 k i k_i ki k j k_j kj 的数值调换(约数个数仍然是不变的),这样对应的 x x x 当然更小

综上, x x x的表达式 x = ∏ p i k i x=\prod p_i^{k_i} x=piki,一定是 ∀ p i < p j , k i ≥ k j \forall p_i<p_j,k_i≥k_j pi<pj,kikj
所以我们爆搜就行了


>代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;

const LL p[100] = {0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
int T, ans2;
LL n, ans1;

LL read()
{
	LL ret = 0;
	char cc = getchar();
	while (cc < '0' || cc > '9') cc = getchar();
	while (cc >= '0' && cc <= '9')
	{
		ret = ret * 10 + cc - '0';
		cc = getchar();
	}
	return ret;
}
void dfs (int now, int cnt, LL k, int sum)
{
	if (sum > ans2) ans1 = k, ans2 = sum;
	else if (sum == ans2 && k < ans1) ans1 = k;
	for (int i = 1; i <= cnt; i++)
	{
		k *= p[now];
		if (k > n) break;
		dfs (now + 1, i, k, sum * (i + 1));
	}
}

int main()
{
	ans1 = ans2 = 0;
	n = read();
	dfs (1, 64, 1, 1);
	printf ("%lld", ans1);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值