zoukankan      html  css  js  c++  java
  • 功夫传人


    title: L2-020. 功夫传人
    tags: [acm,天梯赛]

    题目链接

    一门武功能否传承久远并被发扬光大,是要看缘分的。一般来说,师傅传授给徒弟的武功总要打个折扣,于是越往后传,弟子们的功夫就越弱…… 直到某一支的某一代突然出现一个天分特别高的弟子(或者是吃到了灵丹、挖到了特别的秘笈),会将功夫的威力一下子放大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
    

    分析

    师徒关系并不是按照输入的顺序给出的,所以无法一边输入数据一边处理数据,只有等数据全部输入完毕,才可以确定所有的师徒关系,这样才能求出得道者师傅的最终功力是多少。

    但是我的gf就是一边输入数据一边处理数据的,答案竟然对了,,后来我又给她输入了一组测试数据,明显结果错误。测试数据如下

    9 100 1
    2 7 8
    2 4 5
    2 1 6
    0 2
    0 2
    0 2
    1 3
    0 2
    1 2
    

    正确结果是:774

    另外一点就是可能祖师爷就是得道者

    代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<iostream>
    using namespace std;
    int n;
    double z, r;
    struct NODE
    {
        int id;
        int ziN = 0;
        vector<int>ziId;//这里用动态数组,因为不知道每个人的弟子数量的范围,若都开到很大就会内存超限
        double v = 0;//功力
        double nbN = 1;//功力被放大的倍数
    } node[100001];
    double  tiao()//遍历这一棵树
    {
        double sum = 0;
        int s = 0;
        queue<NODE>q;
        if (node[0].nbN != 1)//祖师爷是得道者
        {
            node[0].v *=  node[0].nbN;
            sum = node[0].v;
        }
        q.push(node[0]);
        while (!q.empty())
        {
            NODE t;
            t = q.front();
            q.pop();
            for (int i = 0; i < t.ziId.size(); i++)
            {
                if (t.ziId[i] != -1)
                {
    
                    node[t.ziId[i]].v = t.v * (1 - 0.01 * r);
                    if (node[t.ziId[i]].nbN != 1)
                    {
                        node[t.ziId[i]].v *= node[t.ziId[i]].nbN;
                        sum += node[t.ziId[i]].v;
                    }
                    //printf("%d	%lf
    ",t.ziId[i],node[t.ziId[i]].v);
                    q.push(node[t.ziId[i]]);
                }
            }
        }
        return sum;
    }
    int main()
    {
        scanf("%d%lf%lf", &n, &z, &r);
        node[0].id = 0;
        node[0].v = z;
        for (int i = 0; i < n; i++)
        {
            int m;
            scanf("%d", &m);
            if (m == 0)
            {
                int t;
                scanf("%d", &t);
                node[i].id = i;
                node[i].nbN = t;
                continue;
            }
            for (int j = 0; j < m; j++)
            {
                int t;
                scanf("%d", &t);
                node[i].ziId.push_back(t);
                node[t].id = t;
            }
        }
        printf("%d
    ", (int)tiao());
        return 0;
    }
    
    /*
    9 100 1
    2 7 8
    2 4 5
    2 1 6
    0 2
    0 2
    0 2
    1 3
    0 2
    1 2
    */
    
    
  • 相关阅读:
    Scrapy 概览笔记
    Python 依赖版本控制 (requirements.txt 文件生成和使用)
    Python 虚拟空间的使用
    macOS 所有版本 JDK 安装指南 (with Homebrew)
    鉴权那些事
    Java 位运算符和 int 类型的实现
    ASP.NET Core 入门教程 5、ASP.NET Core MVC 视图传值入门
    如何做好一次知识或技术分享
    ASP.NET Core 入门教程 4、ASP.NET Core MVC控制器入门
    ASP.NET Core 入门教程 3、ASP.NET Core MVC路由入门
  • 原文地址:https://www.cnblogs.com/dccmmtop/p/6710402.html
Copyright © 2011-2022 走看看