zoukankan      html  css  js  c++  java
  • BZOJ 3629 [JLOI2014] 聪明的燕姿 dfs

    题目描述

    阴天傍晚车窗外
    未来有一个人在等待
    向左向右向前看
    爱要拐几个弯才来
    我遇见谁会有怎样的对白
    我等的人他在多远的未来
    我听见风来自地铁和人海
    我排着队拿着爱的号码牌
    城市中人们总是拿着号码牌,不停寻找,不断匹配,可是谁也不知道自己等的那个人是谁。可是燕姿不一样,燕姿知道自己等的人是谁,因为燕姿数学学得好!燕姿发现了一个神奇的算法:假设自己的号码牌上写着数字S,那么自己等的人手上的号码牌数字的所有正约数之和必定等于S。
    所以燕姿总是拿着号码牌在地铁和人海找数字(喂!这样真的靠谱吗)可是她忙着唱《绿光》,想拜托你写一个程序能够快速地找到所有自己等的人。

    输入

    输入包含k组数据(k<=100)

    输出

    对于每组数据,输出有两行,第一行包含一个整数m,表示有m个等的人,第二行包含相应的m个数,表示所有等的人的号码牌。注意:你输出的号码牌必须按照升序排列。

    样例输入

    42

    样例输出

    3
    20 26 41
    鬼知道这是dfs

    首先要知道一些数学知识

    S=(1+p1+p1^2+p1^3+...+p1^k1)*(1+p2+p2^2+p2^3+...+p2^k2)*...

    而p1^k1,p2^k2...就是对S进行唯一分解得到的东西

    然后对每一个质数进行枚举,看一大坨东西(1+p1+p1^2+p1^3+...+p1^x)(x<=k1)能否被S整除如果可以的话就给这个数乘上p1^x,继续dfs然后就xjb搞一搞就好了。

    #define MAXN 100005
    #include <cstring>
    #include <stdio.h>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    ll prime[MAXN],k,Ans[MAXN];
    int cnt;
    bool _prime[MAXN];
     
     
    void get_prime(){
        for(int i=2;i<100000;i++){
            if(!_prime[i])
                prime[++cnt]=i;
            for(int j=1;j<=cnt&&prime[j]*i<=100000;j++){
                _prime[i*prime[j]]=1;
                if(i%prime[j]==0)break;
            }
        }
    }
     
    bool Judge(ll x){
        if(x==1)return 1;
        for(ll i=1;prime[i]*prime[i]<=x;i++)
            if(x%prime[i]==0)return 0;
        return 1;
    }
     
    void dfs(ll now,int pos,ll left){
        if(left==1){
            Ans[++Ans[0]]=now;
            return;
        }
        if((left-1)>=prime[pos] && Judge(left-1))
            Ans[++Ans[0]]=(left-1)*now;
        for(int i=pos;prime[i]*prime[i]<=left;i++){
            ll sum=prime[i]+1,power=prime[i];
            for(;sum<=left;power*=prime[i],sum+=power)
                if(left%sum==0)
                    dfs(now*power,i+1,left/sum);
        }
    }
     
    int main(){
        get_prime();
        while(~(scanf("%lld",&k))){
            Ans[0]=0;
            dfs(1,1,k);
            printf("%d
    ",Ans[0]);
            sort(&Ans[1],&Ans[Ans[0]+1]);
            for(int i=1;i<=Ans[0];i++)printf("%d ",Ans[i]);
            if(Ans[0])printf("
    ");
        }
    }





  • 相关阅读:
    java内部类案例
    java内部类之成员内部类之局部内部类
    java内部类之成员内部类之匿名内部类
    java静态内部类
    java内部类之成员内部类实例
    java内部类之成员内部类
    UDP和TCP的区别和联系
    SSM
    连接各种数据库
    JDBC数据库连接
  • 原文地址:https://www.cnblogs.com/Cooook/p/7738531.html
Copyright © 2011-2022 走看看