功夫传人[天梯赛]

题目描述

在这里插入图片描述

输入样例
10 18.0 1.00
3 2 3 5
1 9
1 4
1 7
0 7
2 6 1
1 8
0 9
0 4
0 3
输出样例
404

思路

1.初始化
将每个人的关系用树表示,具体存储存储每个人的徒弟,以及得道者的功力放大倍数
2.遍历关系数
从祖师爷(第0代)开始
如果当前编号对应的人有子节点(徒弟),继续找子节点(徒弟)的子节点(徒弟),直到找到叶节点(没有徒弟的人),则该点对应的人是得道者,将其功力值加入最后结果

样例解释

样例对应的关系树如下,编号为4,7,8,9的人为得道者,假设距离祖师爷为x,则每个得道者对应的功力值为:祖师爷的功力值 * pow(r, x) * 功力放大倍数
在这里插入图片描述

AC代码

#include <iostream>
#include <cstdio> 
#include <cmath>
#include <vector>
using namespace std;
const int N = 100010;
double skill[N]; //skill[i]表示编号为i的人是得道者,功力放大倍数为 skill[i]
vector<int> generation[N]; //generation[i][j]表示编号为i的人徒弟有 generation.size()个,编号为j 
double sum, z, r;;
void dfs(int idx, int power)
{
	if(generation[idx].size() == 0) //编号为index的人是得道者 
		sum += z * pow(r, power) * skill[idx];
	else
	{
		for(int i = 0; i < generation[idx].size(); i ++) dfs(generation[idx][i], power + 1);
	}
}
int main()
{
	int n, p = 1;
	cin >> n >> z >> r;
    r = 1 - r / 100;
	for(int i = 0; i < n; i ++) //建立关系树 
	{
		int k, id;
		cin >> k;
		if(!k) cin >> skill[i];
		while(k --)
		{
			cin >> id;
			generation[i].push_back(id);
		}
	}
	dfs(0, 0); //第0代(祖师爷),距离祖师爷的距离 
	cout << (int)sum << endl;
	return 0;  
}

欢迎批评指正!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值