zoukankan      html  css  js  c++  java
  • 【PAT-L2-020】功夫传人

    链接:https://www.patest.cn/contests/gplt/L2-020

    一门武功能否传承久远并被发扬光大,是要看缘分的。一般来说,师傅传授给徒弟的武功总要打个折扣,于是越往后传,弟子们的功夫就越弱…… 直到某一支的某一代突然出现一个天分特别高的弟子(或者是吃到了灵丹、挖到了特别的秘笈),会将功夫的威力一下子放大N倍 —— 我们称这种弟子为“得道者”。

    这里我们来考察某一位祖师爷门下的徒子徒孙家谱:假设家谱中的每个人只有1位师傅(除了祖师爷没有师傅);每位师傅可以带很多徒弟;并且假设辈分严格有序,即祖师爷这门武功的每个第i代传人只能在第i-1代传人中拜1个师傅。我们假设已知祖师爷的功力值为Z,每向下传承一代,就会减弱r%,除非某一代弟子得道。现给出师门谱系关系,要求你算出所有得道者的功力总值

    输入格式:

    输入在第一行给出3个正整数,分别是:N(<=105)——整个师门的总人数(于是每个人从0到N-1编号,祖师爷的编号为0);Z——祖师爷的功力值(不一定是整数,但起码是正数);r ——每传一代功夫所打的折扣百分比值(不超过100的正数)。接下来有N行,第i行(i=0, ..., N-1)描述编号为i的人所传的徒弟,格式为:

    Ki ID[1] ID[2] ... ID[Ki]

    其中Ki是徒弟的个数,后面跟的是各位徒弟的编号,数字间以空格间隔。Ki为零表示这是一位得道者,这时后面跟的一个数字表示其武功被放大的倍数。

    输出格式:

    在一行中输出所有得道者的功力总值,只保留其整数部分。题目保证输入和正确的输出都不超过1010

    输入样例:

    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

    比赛时用找父节点的做法,最后一组一直TLE啊啊啊 ╭(╯^╰)╮

    如果从每个传道者开始向上找父亲的话,最坏的复杂度N^N

    正确的做法从0点开始向下搜,记录层数的信息 bfsdfs都可以,注意0如果是传道者需要特判,就这样。

    想通了后感觉自己好水啊o(╥﹏╥)o~什么时候才能像泰神一样优秀呢

    dfs

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int N = 100005;
     5 int bei[N];
     6 double sum = 0, z, r;
     7 
     8 vector<int>V[N];
     9 void dfs(int s, int ceng)
    10 {
    11     for(unsigned int i = 0; i < V[s].size(); i++)
    12     {
    13         int v = V[s][i];
    14         if(bei[v])
    15         {
    16             sum += bei[v]*z*pow(1-r*0.01, ceng);
    17             continue;
    18         }
    19         dfs(v, ceng+1);
    20     }
    21 }
    22 int main()
    23 {
    24     int n, m, a;
    25     scanf("%d%lf%lf", &n, &z, &r);
    26     for(int i = 0; i < n; i++)
    27     {
    28         scanf("%d", &m);
    29         if(m==0)
    30         {
    31             scanf("%d", &a);
    32             bei[i] = a;
    33             continue;
    34         }
    35         while(m--)
    36         {
    37             scanf("%d", &a);
    38             V[i].push_back(a);
    39         }
    40     }
    41     if(bei[0]) sum += bei[0]*z;
    42     dfs(0, 1);
    43     LL ans = (int)sum;
    44     printf("%lld
    ", ans);
    45     return 0;
    46 }

    bfs

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int N = 100005;
     5 int bei[N];
     6 double sum = 0, z, r;
     7 struct node
     8 {
     9     int id, ceng;
    10 };
    11 vector<int>V[N];
    12 void bfs()
    13 {
    14     queue<node>Q;
    15     node s, t;
    16     s.id = 0, s.ceng = 0;
    17     Q.push(s);
    18     if(bei[0]) sum += bei[0]*z;
    19     while(!Q.empty())
    20     {
    21         s =  Q.front();
    22         Q.pop();
    23         for(unsigned int i = 0; i < V[s.id].size(); i++)
    24         {
    25             t.id = V[s.id][i];
    26             t.ceng = s.ceng+1;
    27             if(bei[t.id])
    28                 sum += bei[t.id]*z*pow(1-r*0.01, t.ceng);
    29             Q.push(t);
    30         }
    31     }
    32 }
    33 int main()
    34 {
    35     int n, m, a;
    36     scanf("%d%lf%lf", &n, &z, &r);
    37     for(int i = 0; i < n; i++)
    38     {
    39         scanf("%d", &m);
    40         if(m==0)
    41         {
    42             scanf("%d", &a);
    43             bei[i] = a;
    44             continue;
    45         }
    46         while(m--)
    47         {
    48             scanf("%d", &a);
    49             V[i].push_back(a);
    50         }
    51     }
    52     bfs();
    53     LL ans = (int)sum;
    54     printf("%lld
    ", ans);
    55     return 0;
    56 }
  • 相关阅读:
    异步运行
    ES6新增----深入理解generator
    ES6新增(箭头函数)
    ES6新增(有关变量)
    I2C写时序图[转]
    kernel中,dump_stack打印调用栈,print_hex_dump打印一片内存,记录一下
    http://man.linuxde.net/ 转
    Linux网络
    Linux基础:用tcpdump抓包(转)
    指针长度问题,不同架构的指针长度不同,可能32位,也可能64位,与unsigned long长度相同
  • 原文地址:https://www.cnblogs.com/lesroad/p/8652998.html
Copyright © 2011-2022 走看看