洛谷 P1463 [POI2002][HAOI2007]反素数

题目链接

题目描述

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

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

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

题目分析

根据反质数的概念和算术基本定理,我们可以知道,若x为反质数,则x=∏piai(pi为质数,pi>pi-1,ai<=ai-1)(对于最后一项限制的说明:若存在ai>ai-1,则交换ai与ai-1所得的数与原来的数因数个数相等,但比原来的数小,故原数非反质数)。

这样,我们只需要从小到大枚举质数,对于每一个质数枚举它的指数进行搜索,判断生成的数是否是满足条件的最大反质数即可,注意如果当前生成的数因数个数与记录的最大因数个数相等,但数本身比记录值小,需要更新记录值,因为原来的数已经不是反质数了。

对于枚举质数的范围,因为2×3×5×7×11×13×17×19×23×29大于N的最大值,故只需枚举这几个质数即可。同时,由于231也已经大于N的最大值,所以指数的上界为31。

代码

 1 #include<cstdio>
 2 using namespace std;
 3 const int prime[11]={0,2,3,5,7,11,13,17,19,23,29};
 4 unsigned long long n,max_factor,ans;
 5 void dfs(unsigned long long step,unsigned long long sum,unsigned long long factor,unsigned long long maxn)
 6 {
 7     if(step>10||sum>n)
 8         return;
 9     if(max_factor<factor)
10     {
11         max_factor=factor;
12         ans=sum;
13     }
14     else if(max_factor==factor&&ans>sum)
15         ans=sum;
16     unsigned long long t=1;
17     for(unsigned long long i=1;i<=maxn;++i)
18     {
19         t*=prime[step];
20         dfs(step+1,sum*t,factor*(i+1),i);
21     }
22     return;
23 }
24 int main()
25 {
26     scanf("%llu",&n);
27     dfs(1,1,1,31);
28     printf("%llu",ans);
29     return 0;
30 }
反素数
原文地址:https://www.cnblogs.com/Psephurus-Gladius-zdx/p/10801881.html