• 「一本通 5.2 例 3」数字转换


    一道被划分在树形dp中的题,虽然好像没什么关系。。。

    题目描述

    如果一个数

    的约数和 (不包括他本身)比他本身小,那么 可以变成 也可以变成 。例如 可以变为 可以变为 。限定所有数字变换在不超过

    的正整数范围内进行,求不断进行数字变换且不出现重复数字的最多变换步数。

    输入格式

    输入一个正整数

    输出格式

    输出不断进行数字变换且不出现重复数字的最多变换步数。

    样例

    样例输入

    7
    

    样例输出

    3
    

    样例说明

    一种方案为

    数据范围与提示

    对于

    的数据,

    先预处理建边,(注意加优化,防止超时)然后就成了找树的最大直径,先dfs找一条最长边,在从此点开始dfs

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    
    const int maxn = 8e4+10;
    
    int n,head[maxn],size=0,maxx,ru[maxn],pos=0;
    
    bool vis[maxn];
    
    struct edge{
        int v,nex;
    }e[maxn<<1];
    
    void adde(int u,int v){
        e[size].v=v;e[size].nex=head[u];head[u]=size++;
    }
    
    void dfs(int u,int dep){
        vis[u]=1;
        if(ru[u]==1){
            if(dep>maxx) maxx=dep,pos=u;
        }
        for(int i=head[u];~i;i=e[i].nex){
            int v=e[i].v;if(vis[v]) continue;
            dfs(v,dep+1);
        }
    }
    
    int main(){
        memset(head,-1,sizeof(head));
        scanf("%d",&n);
        for(int i=2;i<=n;i++){
            int tt=1;
            for(int j=2;j*j<=i;j++)
                if(i%j==0) tt+=j+i/j;//优化,这样就不用一直枚举到i
            if((int)sqrt(i)*(int)sqrt(i)==i) tt-=(int) sqrt(i);//特判
            if(tt>=i) continue;
            adde(i,tt);adde(tt,i);ru[i]++;ru[tt]++;
        }
        dfs(1,0);
        memset(vis,0,sizeof(vis));
        maxx=0;
        dfs(pos,0);//两次dfs
        printf("%d",maxx);
        return 0;
    }
    View Code
  • 相关阅读:
    VBA基础一:对象、属性、方法、变量
    js画吊线图
    C++读取硬盘物理序列号-非管理员权限
    什么是句柄?
    2020年WIN7系统的几个问题处理
    静态分析:IDA逆向代码段说明 text、idata、rdata、data
    入门级汇编语法句读
    Ollydbg 单步跟踪F8
    IDA使用之旅(四)
    CSP认证201409-1-相邻数对-(Java)100分
  • 原文地址:https://www.cnblogs.com/plysc/p/10576826.html
Copyright © 2020-2023  润新知