反素数 -数学+搜索
Solution:
引理一:
1N中最大的反质数为,就是1N中约数最多的数里最小的一个
引理二:
若把最大的反质数x质因数分解:
\[x=(p1^{c1})*(p2^{c2})*......*(pk^{ck}) \]若p1≤p2≤......≤pk,那么一定满足:c1≥c2≥......≥ck
证明略。
同时注意到N只有2e9,那么这意味着任何一个数都有不超过10个质因子(最小的10个质因子相乘>2e9)
所以可以直接dfs,枚举每一个质因子的指数,且使之满足引理二、乘积不超过N。
在以上限制下,搜索量不大,每搜到一个数就更新一下ans即可。
Code:
#include <bits/stdc++.h>
#define RG register
#define IL inline
#define int long long
using namespace std;
IL int gi(){
char ch=getchar(); int x=0,q=0;
while(ch<'0'||ch>'9') q=ch=='-'?1:q,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return q?-x:x;
}
const int INF=2147483647;
int n,tot,ans=INF,pr[11]={0,2,3,5,7,11,13,17,19,23,29},cnt[11];
IL int check() {
RG int i,sum=1;
for (i=1;i<=10&&cnt[i];++i) sum*=(cnt[i]+1);
if (sum>tot) return tot=sum,1;
if (sum==tot) return 2;
return 0;
}
void DFS(int x,int now) {
RG int i,fl;
if (x==11) {
if ((fl=check())!=0) {
if (fl==1) ans=now;
else ans=min(ans,now);
}
return;
}
for (i=cnt[x-1];i>=0;--i)
if (now*pow(pr[x],i)<=n)
cnt[x]=i,DFS(x+1,now*pow(pr[x],i)),cnt[x]=0;
}
signed main() {
n=gi(),cnt[0]=30,DFS(1,1);
printf("%lld\n",ans);
return 0;
}