pta l2-20(功夫传人)

题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805059118809088

题意:给定n个人,编号0~n-1,0为祖先,每个人有一个师傅,每次从师傅传功夫到徒弟时,功力值会削弱r,但可能会出现得道者,功力翻n倍,计算所有得道者功力值之和。

思路:因为计算功力值时要从祖先开始逐渐向下计算,所以我们需要存储每个人的徒弟,然后从上向下遍历即可,我这里用的是邻接表实现的,定义maxn个表头结点head,head[i]其中包括它的第一个徒弟编号nxt,翻的倍数,功力值;定义maxn个表结点,指向其兄弟结点。然后用dfs从祖先编号0开始搜即可,但我被两个细节点卡了一个多小时,卡到崩溃QAQ:1.输入的r是[0,100]的值,还需除100; 2. 我写代码没带脑子,在dfs函数中用全局变量tmp作为指向徒弟的指针,然后程序一直在那运行错误的结果...

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3
 4 const int maxn=100005;
 5 struct node{
 6     int nxt,bg;
 7     double gl;
 8 }head[maxn];
 9
10 int n,k,tmp,nxt[maxn];
11 double z,r,sum;
12
13 void dfs(int p){
14     if(head[p].bg)
15         sum+=head[p].gl*head[p].bg;
16     else{
17         int t=head[p].nxt;
18         while(t){
19             head[t].gl=head[p].gl*r;
20             dfs(t);
21             t=nxt[t];
22         }
23     }
24 }
25
26 int main(){
27     scanf("%d%lf%lf",&n,&z,&r);
28     r=1.0-0.01*r;
29     head[0].gl=z;
30     for(int i=0;i<n;++i){
31         scanf("%d",&k);
32         if(!k)
33             scanf("%d",&head[i].bg);
34         else
35             while(k--){
36                 scanf("%d",&tmp);
37                 nxt[tmp]=head[i].nxt;
38                 head[i].nxt=tmp;
39             }
40     }
41     dfs(0);
42     printf("%lld\n",(long long)sum);
43     return 0;
44 }

原文地址:https://www.cnblogs.com/FrankChen831X/p/10573996.html

时间: 2024-10-26 18:36:24

pta l2-20(功夫传人)的相关文章

L2-020. 功夫传人

一门武功能否传承久远并被发扬光大,是要看缘分的.一般来说,师傅传授给徒弟的武功总要打个折扣,于是越往后传,弟子们的功夫就越弱…… 直到某一支的某一代突然出现一个天分特别高的弟子(或者是吃到了灵丹.挖到了特别的秘笈),会将功夫的威力一下子放大N倍 —— 我们称这种弟子为“得道者”. 这里我们来考察某一位祖师爷门下的徒子徒孙家谱:假设家谱中的每个人只有1位师傅(除了祖师爷没有师傅):每位师傅可以带很多徒弟:并且假设辈分严格有序,即祖师爷这门武功的每个第i代传人只能在第i-1代传人中拜1个师傅.我们假

PAT L2-020 功夫传人

https://pintia.cn/problem-sets/994805046380707840/problems/994805059118809088 一门武功能否传承久远并被发扬光大,是要看缘分的.一般来说,师傅传授给徒弟的武功总要打个折扣,于是越往后传,弟子们的功夫就越弱…… 直到某一支的某一代突然出现一个天分特别高的弟子(或者是吃到了灵丹.挖到了特别的秘笈),会将功夫的威力一下子放大N倍 —— 我们称这种弟子为“得道者”. 这里我们来考察某一位祖师爷门下的徒子徒孙家谱:假设家谱中的每个

天梯赛练习(一)

L2-017. 人以群分 题意: 给定n个正整数,  然后分成规模相差尽可能接近的两类, 这两类之和相差要尽可能大 分析: 直接排序, 然后分成两部分即可 1 #include <bits/stdc++.h> 2 using namespace std; 3 int a[123456]; 4 int sum(int l , int r){ 5 int ans = 0; 6 for(int i = l; i <= r; i++) ans += a[i]; 7 return ans; 8 }

poj 3253 Fence Repair

Fence Repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 40465   Accepted: 13229 Description Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needs N (1 ≤ N ≤ 20,000)

一个数组类【模板类】

这学期的大作业感觉挺简单的,就是写一个模板类MyList,实现一些Python中的list的操作(类似于c++中的vector,但是不支持迭代器).这些功能都很简单,唯一麻烦的就是模板类特别烦,特别是友元函数,首先要声明这个类,然后声明是函数的声明,然后是类中友元函数的声明,最后是实现.友元函数的声明还有一个问题就是声明时在函数名后面要加上一个<>就像这样: friend void Qsort<>(T a[],int low,int high,bool less); 还有一个要注意

列表、元组、字典

列表def append(self, p_object): '''在列表末尾添加一个元素'''l2 = [20,40,70,100]l2.append(1)l2.append(2)l2.append(3)print(l2)[20, 40, 70, 100, 1, 2, 3] def count(self, value): '''总计一个元素在列表中出现的次数''' l2 = [20,40,70,100,20,70,80,20]print(l2.count(20))3 def extend(sel

leetcode速度才是王道 2. Add Two Numbers

2. Add Two Numbers You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. Input: (2 -> 4 -> 3)

Leetcode 23.Merge Two Sorted Lists Merge K Sorted Lists

Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. 依次拼接 复杂度 时间 O(N) 空间 O(1) 思路 该题就是简单的把两个链表的节点拼接起来,我们可以用一个Dummy头,将比较过后的节点接在这个Dummy头之后.最后

Maximum Product of Word Lengths -- LeetCode

Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0. Example