描述
如果一个大于等于 1 的正整数 n ,满足所有小于 n 且大于等于 1 的所有正整数的约数个数都小于 n 的约数个数,则 n 是一个 Antiprime 数。譬如:1,2,4,6,12,24 ,它们都是 Antiprime 数。
请你计算不大于 n 的最大 Antiprime 数。
输入
一行一个正整数 n 。
输出
只包含一个整数,即不大于 n 的最大 Antiprime 数。
样例输入
1000
样例输出
840
提示
对于 10%的数据,1≤n≤10^3
对于 40%的数据,1≤n≤10^6
对于 100%的数据,1≤n≤2×10^9
首先来讲一下正解吧
很容易发现
不大于n的最大的antiprime一定是1~n中质因子最多的数中最小的那一个
又因为 而
所以说1~n的最大的antiprime的质因子不会超过10个
而且每一个质因子的指数一定是递减的
如果有一个质因子的指数比前面的大,那么把他们两个的指数交换就能得到一个更小的约数个数相同的数
所以说指数一定递减
那么我们可以直接考虑深搜
枚举每个质因子的指数
#include<bits/stdc++.h>
using namespace std;
inline int read(){
char ch=getchar();
int res=0;
while(!isdigit(ch))ch=getchar();
while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res;
}
#define ll long long
const ll inc[12]={1,2,3,5,7,11,13,17,19,23,29,31};
ll n;
ll minn=1e9,mnum=-100000;
void dfs(ll now,int k,ll num,int mst){
if(mnum<num){
minn=now,mnum=num;
}
if(mnum==num&&minn>now){
minn=now,mnum=num;
}//
if(k>10)return;
ll p=now;
for(int i=1;i<=mst;i++){
if(p*inc[k]>n)break;
p=p*inc[k];
dfs(p,k+1,num*(i+1),i);
}
}
int main(){
n=read();
dfs(1,1,1,31);
cout<<minn<<'
';
}
当然我们也会发现反素数的个数其实是很少的
那么我们也可以考虑打表
枚举出2e9以内的所有反素数
直接查找就可以了
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll antip[1000] = {1396755360,1102701600,735134400,698377680,551350800,367567200,294053760,245044800,183783600,147026880,122522400,110270160,73513440,61261200,43243200,36756720,32432400,21621600,17297280,14414400,10810800,8648640,7207200,6486480,4324320,3603600,2882880,2162160,1441440,1081080,720720,665280,554400,498960,332640,277200,221760,166320,110880,83160,55440,50400,45360,27720,25200,20160,15120,10080,7560,5040,2520,1680,1260,840,720,360,240,180,120,60,48,36,24,12,6,4,2,1};//当然这里并没有1000个,只是开大数组而已
ll n;
int main(){
cin>>n;
for(int i=999;i>=0;i--){
if(antip[i]>n&&antip[i+1]<n){
cout<<antip[i+1];
return 0;
}
}
cout<<antip[0];
}