HYSBZ 1053 反质数
input
n 1<=n<=2000000000
output
不大于n的最大反质数
对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。
如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数。例如,整数1,2,4,6等都是反质数。
做法:直接打表查找
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <iostream> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <ctime> 11 #include <cmath> 12 #include <cctype> 13 #define MAX 100000 14 #define INF 2000000000 15 #define LL long long 16 int cas=1,T,n,a[MAX],an,p[10]={2,3,5,7,11,13,17,19,23,29}; 17 struct node 18 { 19 int b[10],n,v,g; //b数组是质数对应的次方,v是值,g是约数个数,n是质因子个数 20 bool operator<(node a)const { return v>a.v; } 21 }; 22 void init() 23 { 24 std::priority_queue<node>q; 25 a[0]=1;an=1; 26 int ming=1;//当前最大的约数个数 27 node u; 28 u.v=2;u.n=0;u.b[0]=1;u.g=2; 29 q.push(u); 30 while(!q.empty()) 31 { 32 u=q.top();q.pop(); 33 // printf("%d %d %d\n",u.v,u.g,u.n); 34 if(u.g>ming) { ming=u.g;a[an++]=u.v; }//比当前最大约数个数大的统计 35 else continue; 36 for(int i=0;i<=u.n;i++)//出队后将每个质数对应的次方加一放进队列里 37 { 38 node v; 39 memcpy(&v,&u,sizeof(node)); 40 LL tmp=(LL)v.v*p[i]; 41 v.b[i]++; 42 v.g=v.g/v.b[i]*(v.b[i]+1); 43 if(tmp<=INF) v.v=tmp; 44 if(tmp<=INF&&v.g>ming) q.push(v); 45 // printf("aaa:%d %d %d\n",v.v,v.g,v.n); 46 } 47 if(u.n+1<9)//增加一个质因子 48 { 49 node v; 50 memcpy(&v,&u,sizeof(node)); 51 v.n++;v.b[v.n]=1;v.g*=2; 52 LL tmp=(LL)v.v*p[v.n]; 53 if(tmp<=INF) v.v=tmp; 54 if(tmp<=INF&&v.g>ming) q.push(v); 55 } 56 } 57 a[an++]=INF+10; 58 printf("%d\n",an); 59 for(int i=0;i<an;i++) printf("%d,",a[i]); 60 } 61 int main() 62 { 63 //freopen("in","r",stdin); 64 //scanf("%d",&T); 65 init(); 66 while(scanf("%d",&n)==1) printf("%d\n",*(std::upper_bound(a,a+an,n)-1)); 67 //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC); 68 return 0; 69 }