[luogu]P1463 [SDOI2005]反素数ant[dfs][数学][数论]

[luogu]P1463

[SDOI2005]反素数ant

——!x^n+y^n=z^n

题目描述

对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。

如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。

现在给定一个数N,你能求出不超过N的最大的反质数么?

输入输出格式

输入格式:

一个数N(1<=N<=2,000,000,000)。

输出格式:

不超过N的最大的反质数。

输入输出样例

输入样例1#:

1000

输出样例1#:

840


算术基本定理,质因数分解:

N=a1^k1*a2^k2*L*an^kn,约数个数:(k1+1)*(k2+1)*L*(kn+1)。

一开始以为贪心就行了,尽量多乘素数,后面发现...休想哦。40就过不了,唉,不过爆搜就可以过了呵呵...

记录当前的数st,当前搜到第几个素数(11个就很够了,再乘的话肯定存在前面某一种素数组合使其约数与当前相同,不过肯定是小的比较优啊),还有就是约数个数,约数相同的话要选择st小的,后面不叫反素数。

代码:

 1 //2017.10.30
 2 //dfs math
 3 #include<iostream>
 4 #include<cstdio>
 5 #include<cstring>
 6 using namespace std;
 7 typedef long long ll ;
 8 inline ll read();
 9 namespace lys{
10     int pri[50]={0,2,3,5,7,11,13,17,19,23,29,31,37,41};
11     ll ans=1,n;
12     int MAX;
13     void dfs(ll st,int x,ll num){
14         if(num>MAX||(num==MAX&&st<ans)){
15             ans=st;
16             MAX=num;
17         }
18         int i=0;
19         ll base=1;
20         if(x>11) return ;
21         while(base*st<=n){
22             dfs(st*base,x+1,1LL*(++i)*num);
23             base*=pri[x];
24         }
25     }
26     int main(){
27         n=read();
28         dfs(1,1,1);
29         printf("%lld
",ans);
30         return 0;
31     }
32 }
33 int main(){
34     lys::main();
35     return 0;
36 }
37 inline ll read(){
38     ll kk=0,ff=1;
39     char c=getchar();
40     while(c<'0'||c>'9'){
41         if(c=='-') ff=-1;
42         c=getchar();
43     }
44     while(c>='0'&&c<='9') kk=kk*10+c-'0',c=getchar();
45     return kk*ff;
46 }
原文地址:https://www.cnblogs.com/_inx/p/7753669.html