BZOJ 1053: [HAOI2007]反素数ant 数论,DFS

来源:互联网 发布:淘宝网官方网站登入 编辑:程序博客网 时间:2024/05/17 05:03

Description

  对于任何正整数x,其约数的个数记作g(x)。例如g(1)=1、g(6)=4。如果某个正整数x满足:g(x)>g(i)
,则称x为反质数。例如,整数1,2,4,6等都是反质数。现在给定一个数N,你能求出不超过N的最大的反质数么

Input

  一个数N(1<=N<=2,000,000,000)。
Output

  不超过N的最大的反质数。
Sample Input
1000
Sample Output
840

解题思路:

结论一:一个数约数个数=所有素因子的次数+1的乘积结论二:一个2000000000以内的数字不会有超过12个素因子结论三:较小的数的指数一定大于等于较大的数的指数有了以上3个结论这个题就是水题了。。准备工作: 预处理出前12个素数。然后就可以暴搜了, 将递归层数设定为第 dep 个素数. 枚举该素数选择多少个, 下一层的素数一定不会超过这个值。当dep == 12时更新答案并返回. 如果当前数大于当前答案并且因数个数多于答案, 更新答案; 如果当前数小于答案但是因数个数多于答案, 那么也要更新, 因为原有答案不再合法。

代码如下:

#include <bits/stdc++.h>using namespace std;typedef long long LL;LL n;int ans = 1, num = 1; //数的大小, 约数个数int pri[15] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};void dfs(int dep, LL now, int cnt, int limit){ //第dep层素数,当前数大小,约数的个数,该素数选多少    if(dep == 12){        if(now > ans && cnt > num) {ans = now; num = cnt;}        if(now <= ans && cnt >= num) {ans = now; num = cnt;}        return;    }    LL t = 1;    for(int i = 0; i <= limit; i++){        dfs(dep + 1, now * t, cnt * (i + 1), i);        t *= pri[dep];        if(now * t > n) break;    }}int main(){    scanf("%lld", &n);    dfs(1, 1, 1, 30);    printf("%d\n", ans);    return 0;}
0 0
原创粉丝点击