zoukankan      html  css  js  c++  java
  • bzoj3629: [JLOI2014]聪明的燕姿(数学 + 搜索)

    bzoj3629

    题目描述:给定一个数s,求约数之和等于s的所有数。

    输入格式:输入包含k组(k <= 100),每组一个整数s。

    输出格式:对于每组数据,输出两行,第一行一个整数,表示总数,第二行表示所有的数。

    样例输入:

    42

    样例输出:

    3
    20 26 41

    解析:相信大家都很熟悉约数和定理,那么这题便可以用搜索来解决,搜索枚举因数即可。(好像还是搜索比较难打)

    代码如下:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define int long long
     4 using namespace std;
     5 
     6 const int maxn = 1e5;
     7 int s, prime[maxn], mark[maxn], ans[maxn], cnt, tot;
     8 
     9 void prepare(void) { //欧拉筛 
    10     mark[1] = 1;
    11       for (int i = 1; i <= maxn; ++ i) {
    12           if (!mark[i]) prime[++ tot] = i;
    13           for (int j = 1; j <= tot; ++ j) {
    14               if (1ll * prime[j] * i > maxn) break;
    15               mark[prime[j] * i] = 1;
    16           }
    17       }
    18 }
    19 
    20 int pd(int num) { //判断素数
    21     if (num <= maxn) return !mark[num]; //如果找过了就直接用
    22     if (num == 1) return 0; //特判1不是素数 
    23     for (int i = 1; 1ll * prime[i] * prime[i] <= num; ++ i) //试除
    24       if (num % prime[i] == 0) return 0;
    25     return 1;
    26 }
    27 
    28 void dfs(int last, int prod, int rest) { //last:上一个搜的素数,prod:搜到的数,rest:还需要乘上rest达到s
    29     if (rest == 1) { //累加答案  
    30       ans[++ cnt] = prod;
    31       return;
    32     }
    33     if (rest - 1 > prime[last] && pd(rest - 1)) ans[++ cnt] = prod * (rest - 1); //rest - 1要大于prime[last],否则会重复枚举(不用return!) 
    34     for (int i = last + 1; prime[i] * prime[i] <= rest; ++ i) {
    35       for (int j = prime[i], cur = prime[i] + 1; cur <= rest; j *= prime[i], cur += j) { //j是约数的次幂,cur是约数的和 
    36           if (rest % cur == 0) dfs(i, prod * j, rest / cur);
    37       }
    38     } 
    39 }
    40 
    41 signed main() {
    42     prepare();
    43     while (scanf("%lld", &s) != EOF) {
    44       cnt = 0; dfs(0, 1, s); 
    45       sort(ans + 1, ans + 1 + cnt);
    46       printf("%lld
    ", cnt);
    47         for (int i = 1; i <= cnt; ++ i) printf("%lld%c", ans[i], i == cnt ? '
    ' : ' ');
    48     }
    49     return 0;
    50 } 
  • 相关阅读:
    Explain用法
    轻量快速的 Python ASGI 框架 uvicorn
    conda常用命令
    ubuntu 安装并配置zsh
    ubuntu安装zsh终端
    /etc/profile、/etc/bashrc、.bash_profile、.bashrc
    python用List的内建函数list.sort进行排序
    python对象排序
    修改python接口返回给前端的格式封装
    linux设置uwsgi开机自启
  • 原文地址:https://www.cnblogs.com/Gaxc/p/9915789.html
Copyright © 2011-2022 走看看