题目描述
对于任何正整数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
2019/8/21-更新(代码后面写不了了,只能写在前面...):
上午刚做的题,下午老师就讲了,搞得我好像白写了题解o(一︿一+)o,所以就顺便把老师的课件附上来吧!
(别忘了后面还有我自己写的...
首先普及下关于“反素数”的两个性质:
-
性质一:一个反素数的质因子必然是从2开始连续的质数.
-
性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....
然后,我再说下我个人的理解
-
因为题目给出了n的范围,所以我们可得出结论:n的质因子的种数不超过10,所以得到了一条递归边界;
-
因为“反素数”的性质二,所以在两个数约数相等的情况下,更小的那个数就是“反素数”(可以用反证法证明:如果存在a的约数个数与b相等,且a>b。若认为a为“反素数”,那么不满足小于a的数的约数个数都小于a的约数个数,矛盾;)。所以我们要求的答案显然就是不大于n的 约数个数最大的 最小的数(哇这句话真的要好好理解,性质二肥肠关键!;
-
那么应用到本题,在递归的过程中,如果遇到两个数约数个数相同,并且当前得到的数now小于之前得到的数ans,那就更新ans;如果当前求得的数now的约数个数num已经大于之前求到的最大的约数个数tot,那就更新tot,并且别忘了也要更新ans;
-
如果在递归过程中,当前求得值已经大于n,那么就没必要再继续递归下去,直接返回,这就是第二条递归边界;
-
在递归函数中设置一个循环,每进行一个循环,当前递归的质因子的个数就加一,并且此处还可以进行一点剪枝,在循环条件中加入“当前递归的质因子个数 不大于 比其小的质因子的 个数”这个条件;