zoukankan      html  css  js  c++  java
  • 1629:聪明的燕姿

    1629:聪明的燕姿


    时间限制: 1000 ms         内存限制: 524288 KB
    提交数: 103     通过数: 53

    【题目描述】

    城市中人们总是拿着号码牌,不停寻找,不断匹配,可是谁也不知道自己等的那个人是谁。

    可是燕姿不一样,燕姿知道自己等的人是谁,因为燕姿数学学得好!燕姿发现了一个神奇的算法:假设自己的号码牌上写着数字 S

    ,那么自己等的人手上的号码牌数字的所有正约数之和必定等于 S

    所以燕姿总是拿着号码牌在地铁和人海找数字(喂!这样真的靠谱吗)可是她忙着唱《绿光》,想拜托你写一个程序能够快速地找到所有自己等的人。

    【输入】

    输入包含 k

    组数据。

    对于每组数据,输入包含一个号码牌S

    【输出】

    对于每组数据,输出有两行,第一行包含一个整数 m

    ,表示有 m

    个等的人。

    第二行包含相应的 m

    个数,表示所有等的人的号码牌。

    注意:你输出的号码牌必须按照升序排列。

    【输入样例】

    42

    【输出样例】

    3
    20 26 41

    【提示】

    数据范围与提示

    对于 100% 的数据,k100, S2×109

    其实这道题一点都不难

    解答本题的关键在于对唯一分解定理和约数和公式的理解。分解数即可

    代码中left表示被剩下的未被分解的数,sum'表示当前得到的结果,pos表示检索第几个质数。

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=1e6+1;
    bool mark[N];
    int prime[N],tot,ans[N],S;
    inline void Pre()
    {
        int i,j,cnt=0;
        for(i=2;i<=N;i++)
        {
            if(!mark[i]) 
            {
                mark[i]=1;
                prime[++cnt]=i;
            }
            for(int j=1;j<=cnt&&prime[j]<=N/i;j++)
            {
                mark[i*prime[j]]=1;
                if(i%prime[j]==0) break;
            }
        }
        //for(int i=1;i<=100;i++)
        //printf("%d ",prime[i]);
    }
    inline bool judge(int x)
    {
        for(int i=2;i<=sqrt(x);i++)
        if(x%i==0) return false;
        return true;
    }
    void dfs(int pos,int sum,int left)
    {
        if(left==1)
        {
            ans[++tot]=sum;
            return ;
        }
        if(judge(left-1)&&left>prime[pos]) 
        {
            ans[++tot]=sum*(left-1);
        }
        for(int i=pos;prime[i]*prime[i]<=left;i++)
        {
            int Sum=prime[i]+1,tmp=prime[i];
            for(;Sum<=left;tmp*=prime[i],Sum+=tmp)
            {
                if(left%Sum==0)
                dfs(i+1,sum*tmp,left/Sum);
            }
        }
    }
    signed main()
    {
        Pre();
        while(~scanf("%lld",&S))
        {
            tot=0;
            dfs(1,1,S);
            sort(ans+1,ans+tot+1);
            printf("%lld
    ",tot);
            for(int i=1;i<=tot;i++)
            printf("%lld ",ans[i]);
            if(tot) puts("");
        }
        return 0;
    }

    最后,值得注意的是这道题的输出有坑,得自己去WA下试试才知道

  • 相关阅读:
    从json中获取自己想要的属性
    对称加密解密
    springboot 读取resource目录下的文件
    安装nginx 配置了ssl 启动报错
    复利计算--4.0 单元测试之JAVA版-软件工程
    《构建之法》前三章读后感
    单利 复利计算器程序1.0 2.0 3.0 [ 合 ] 之 WEB
    操作系统 实验一 命令解释程序的编写
    单利 复利计算器程序1.0 2.0 3.0 [ 合 ] 之 C语言
    统计实验数据 总结实验结果
  • 原文地址:https://www.cnblogs.com/smartljy/p/11394449.html
Copyright © 2011-2022 走看看