P1463 [POI2001] [HAOI2007] 反素数 (ybtoj)

思路:先写出30以内的质数(以其作为因数),再深搜每一种小于n的方案,在这之中选最大值;

tips:质数可以单调上升来优化;

根据数据范围,发现最多只需要11层即可搜索到答案,保险搜到12层;

dfs存一个last作为前一层的反素数;

为了成为最大反素数,存下每一个反素数的本身值,以此来判断大小;

因为dfs的反素数的约数只会单调递增,所以可以答案一定合法;

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[20]={0,2,3,5,7,11,13,17,19,23,29,31};//打表
typedef long long LL;
LL n,d,d1;
inline void dfs(LL u,LL last,LL k,LL sum){
	if(u==12) return ;
	LL cnt=1;
	for(int i=2;i<=k+1;i++){
		cnt*=a[u];//本次对于反素数的加的值
		if(last*cnt>n) return ;//判断不能大于n
		if(sum*i>d1) d=last*cnt,d1=sum*i;//d1为了排大小
		else  if(!(sum*i<d1)&&last*cnt<d) d=last*cnt;//d为反素数搜到值
		dfs(u+1,last*cnt,i-1,sum*i);
	}
}
int main(){
	cin>>n;
	dfs(1,1,31,1);
	cout<<d<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值