题解 P1463 【[SDOI2005]反素数ant】
题目解释放在代码注释里面了~
欢迎吐槽与建议
/*
1.
一个数的约数个数=所有素因子的幂次+1的乘积
这个直观的理解就是 2^x*3^y 我能拆出来
2^0*3^0
2^0*3^1
2^0*3^2
……
2^1*3^0
2^1*3^1
……
2^2*3^0
……
2^x*3^0
……
2^x*3^y
根据乘法原理 2一共有x+1个幂 3有y+1个幂 所以就是(x+1)*(y+1)
2.
写一个暴力跑程序会发现一个2000000000以内的数字不会有超过12个素因子
3.
较小的数的幂次一定大于等于较大的数的幂次
之后就是赤裸裸的DFS暴搜了
*/
#include <cstdio>
#include <algorithm>
typedef long long ll;
ll n;
int ans=1,num=1;
ll Max,last;
//1的确不是质数 但是x^0需要用到
int prime[15]={1,2,3,5,7,11,13,17,19,29,31};
//dep的意义是当前的第几个素数 Num是当前数字大小 tot是当前约数的和 limit是上一个素数的幂次对本次的限制约束
void dfs(int dep,ll Num,int tot,int limit){
if(dep==12){
//当前值大于记录值 并且约数也比上次那个多
if(Num > Max && tot> last){
Max = Num;
last = tot;
}
//当前值小于记录值 并且约数也比上次那个多 记录值不合法
/*这里这个“= ”特别说明一下
g(x)>g(i) 0<i<x
当前的值是i 比 x 小满足条件,但是如果g(i)<g(x)或者 g(i)=g(x)都不合法
*/
if(Num <= Max && tot >= last){
Max = Num;
last = tot;
}
return;
}
int mul = 1;
for(int i=0;i<=limit;++i){
dfs(dep+1,Num*mul,tot*(i+1),i);
mul*=prime[dep];
if(Num*mul>n) break;
}
}
int main(){
scanf("%d",&n);
dfs(1,1,1,20);
printf("%lld\n",Max);
return 0;
}