[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 }