[SDOI2005]反素数
题目描述
对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。
如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。
现在给定一个数N,你能求出不超过N的最大的反质数么(即后面没有g比它大的),如有多个,则去最小?
输入输出格式
输入格式:
一个数N(1<=N<=2,000,000,000)。
输出格式:
不超过N的最大的反质数。
输入输出样例
输入样例#1:
1000
输出样例#1:
840
题解:
搜索+数论
可知一个数分解为x=p1^q1*p2^q2*p3^q3...时
因数个数为(q1+1)*(q2+1)*(q3+1)....
解释一下题意:
假设ans<ans2,g(ans)==g(ans2),
因为不满足g(ans)<g(ans2),所以ans后没有反质数。所以搜索时除取最大的g值时
还要判断g值相同时的反质数大小。
预处理出13个质数,因为13个质数积大于2e9,在处理出n之内prime[i]^j的值
存在p[i][j]里。
搜索每一个质数的指数。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 long long n,p[21][40],anss,ans=2e9; 7 int prime[21]; 8 void dfs(int x,long long num,long long sum) 9 {int i; 10 if (sum>n) return; 11 if (num>anss) 12 { 13 anss=num; 14 ans=sum; 15 } 16 if (num==anss) 17 { 18 ans=min(ans,sum); 19 } 20 if (x>13) 21 { 22 return; 23 } 24 for (i=1;i<=36;i++) 25 { 26 if (p[x][i]==0) break; 27 if (p[x][i]&&sum*p[x][i]<=n) 28 { 29 dfs(x+1,num*(i+1),sum*p[x][i]); 30 } 31 } 32 } 33 int main() 34 {int i,j; 35 cin>>n; 36 prime[1]=2;prime[2]=3;prime[3]=5;prime[4]=7; 37 prime[5]=11;prime[6]=13;prime[7]=17;prime[8]=19; 38 prime[9]=23;prime[10]=29;prime[11]=31;prime[12]=37; 39 prime[13]=41; 40 for (i=1;i<=13;i++) 41 { 42 long long x=1; 43 for (j=1;j<=36;j++) 44 {x*=prime[i]; 45 if (x>n) break; 46 p[i][j]=x; 47 } 48 } 49 dfs(1,1,1); 50 cout<<ans; 51 }