【L2-020 功夫传人】天梯赛L2系列详解

天梯赛L2-020 功夫传人

题目详情:

在这里插入图片描述
在这里插入图片描述

思路:

这个题目的看着就感觉需要深搜一下,不妨将样例画出来,思路就突然涌来了。很明显的一道深搜的题目:
题目刚开始输入的一行信息整体的信息:宗门人数,祖师爷功力,功力降低的百分数
就开始输入师徒的信息了:徒弟个数,徒弟编号,如果徒弟个数为0证明这货是个得道者,就是我们要找的人,后面就不是徒弟编号了,而是他功力要增加的倍数。
这里呢我画的图把他们隐藏的编号也写了出来,这个样子更容易让我们画出来我们需要的图。
很明显呢,看着这个图,就知道我们要遍历一棵树。那么肯定是要从头开始遍历的,这个题目不用我们找谁是根节点,题目要求了根节点就是0。直接遍历就好,那么就需要一个遍历的函数了:
我们可以先写一个大致意思的函数,要先考虑它的参数,几个参数呢:这个题目不妨设两个,一个编号,一个功力

void dfs(编号,功力)
{
      if(他有标记)//我们把得道者标记一下
      {
             总功力 += 它的功力
      }
      else
      {
           dfs(它的徒弟,徒弟的功力)
      }
}

具体的实现呢还得是看下文的程序。
在这里插入图片描述

详细代码:

//这个题目本质上就是遍历树。
//利用vector建立一个数组来存树,然后利用只有一个师傅的关系来递归
#include<bits/stdc++.h>
using namespace std;

const int maxn = 100000+5;
vector<int>Next[maxn];//存徒弟的编号
int n;
double z, r, sum=0;//记得sum要设置为全局变量,不然的话就得多传一个参数
double t[maxn]={0};//功力的倍数

void dfs(int id, double z)
{
    if(t[id])//功力翻倍即得道者,可以作为得道者的标志
        sum += z*t[id];

    else
        for(int i=0; i<Next[id].size(); i++)//递归求徒弟们的功力
        {
            dfs(Next[id][i], z*r);//让徒弟的编号进行递归 
        }
}
int main()
{
    cin>>n>>z>>r;
    r = (100-r)/100.0;//先变成百分数方便计算
    int k, id;//徒弟个数,徒弟编号
    for(int i=0; i<n; i++)
    {
        cin>>k;
        if(k)
            for(int j=0; j<k; j++)
            {
                cin>>id;
                Next[i].push_back(id);
            }
        else
            cin>>t[i];//如果功力的倍数不为0,那么就是得道者
    }
    dfs(0,z);//从祖师爷开始递归
    cout<<(int)sum<<endl;//因为要求输出整数部分,直接强制类型转换
}

知识总结:

做这种图和树的深搜题,我的做法是先把图画出来,心中先出一个思路,可以更好的帮助我们解题。
这道题目没有遇到什么偏僻的知识,如果说你L2做到了这道题还没有掌握vector,set,map三种容器的基本使用,那你真的需要去补补这方面的知识。
另外我写题目喜欢用全局变量,一是全局变量有默认取值,二全局变量用起来真的方便,在每个函数中都可以使用,就不用在传参什么的了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值