[海豹海边爆]AcWing198

原题链接:198. 反素数 - AcWing题库

解题思路:因为每个合数都能由质数组成,所以在知道一个数的质因数分解后,便可以通过公式求出每一个数的约数。额外加1是因为这个数可以不选择该质数,等价于乘以该质数的0次方。

\prod_{m}^{i}(Ci+1)

(Ci对应的是每个质数的指数)

而从题目中可以得知最大范围。由最大范围可得以下两个限制条件:只需要考虑最小的10个质数,所有质数的指数之和不超过30。第一个限制条件是因为10个质数相乘便以及超过了2e9,而第二个限制条件也是类似的原因,2^30已经超过,不需要考虑更高范围的数字了。

接着只需要找出约数最多的数字中最小的那一个,因为比其大的数字都不符合条件。为了保证能找到最小的数字,应当保证Ci-1>Ci。因为指数的集合相同时,更大的指数对应更小的质数能让值更小。通过以上限制条件范围已经极小,可以通过DFS完成答案的查找。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int prime[11]={0,2,3,5,7,11,13,17,19,23,29},c[11]={0};//prime记录前10个质数,c记录对应位置质数的指数 
long long max_num=1,max_div=1,n;//max_num记录合法的数据初始值,顺带做1特判,max_div记录当前最大的合法数的约数数量 
void dfs(long long buf_num,long long buf_div,int now){//buf_num记录当前值,buf_div记录当前值的约数,now记录层数,即到了第几个质数 
	if(now==11){//到达11层时说明前10个质数都已经选过,开始判断是否需要更新 
		if(buf_div>max_div||(buf_div==max_div&&buf_num<max_num)){//如果约数大于最大值则直接更新,如果相等则选较小的数 
			max_div=buf_div;
			max_num=buf_num;
		}
		return;
	}
	
	for(int i=0;buf_num<=n&&i<=c[now-1];i++){//循环该质数数量,直到大于n或者该质数的指数超过前一个质数的指数为止 
		c[now]=i;
		dfs(buf_num,buf_div*(c[now]+1),now+1);
		buf_num*=prime[now];
	}
}
int main(){
	cin>>n;
	c[0]=0x7fffffff;//因为c[1]是2,而2是实际上的第一个质数,可以不受前一个质数的指数限制,所以初始化一下赋最大值(超过30就行了) 
	dfs(1,1,1);
	cout<<max_num;
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值