• 递归算法


    1、假定谣言就在10个人之间传播。A0是始作俑者,A0编好谣言后,通过微信从其他9个人中随机选择一个人(Ax)发出去,
    Ax又将此微信消息随机转发给其他8个人(除了自己和给自己转发微信的那个人)中的一个人,此后,
    每个收到此微信消息的人都会随机转发给其他8个人中的某一个人。

    请大家研究以下问题,并编程列举问题(a)到问题(c)中谣言传播的所有路径。

    (a)如果这条谣言在这10人中只被转发了3次,那么该谣言的传播可以有多少种不同的路径?如果被转发了n次呢?

    (b)A0收到第3次转发谣言的概率是多少?

    (c)除A0以外的其他人收到第3次转发谣言的概率是多少?

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication1         //以下代码仅供参考,如有计算或者逻辑的错误,欢迎指正。
    {
        class Program
        {
            /// <summary>
            /// 总体思路: 要输出第三次的传播路径,必须算出第一次的传播路径,然后计算第二次传播路径,然后才能计算第三次的传播路径
            /// 下一次的计算结果依赖上一次的计算结果。
            /// </summary>
            /// <param name="args"></param>
            static void Main(string[] args)
            {
                Console.WriteLine("请输入谣言要转发的次数:");
                //输入转发的次数
                int num = Convert.ToInt32(Console.ReadLine());
                //计算结果
                Compulate(null, 1, num + 1);
                Console.ReadKey();
            }
    
    
            /// <summary>
            /// n为起始参数默认为1   k 为要循环的次数  list为上一次转发保存的路径数据
            /// </summary>
            /// <param name="list"></param>
            /// <param name="n"></param>
            /// <param name="k"></param>
            public static void Compulate(List<string[]> list, int n, int k)
            {
                //保存这一次转发的路径数据
                List<string[]> list1 = new List<string[]>();
                if (n == 1)
                {
                    //如果list为null, 表示第一次开始转发
                    if (list == null)
                    {
                        string a0 = "0";  //表示由 A0是开始传播者
                        // 9表示有9个人传播    0~9  代表  A0 A1  A2 ....A9 十个人
                        for (int i = 0; i <= 9; i++)
                        {
                            //创建一个数组,保存第0个传播者 以及 第一个传播的人
                            string[] s = new string[2];
                            s[0] = a0;  //表示是由A0开始传播
                                        //排除自己传播给自己
                            if (i.ToString() != s[0])
                            {
                                // Console.WriteLine(a0 + "--" + i);
                                s[1] = i.ToString();
                                //把数据保存在泛型容器中
                                list1.Add(s);
                            }
                        }
                    }
                }
                else
                {
                    //打印路径数据
                    if (n == k)
                    {
                        try
                        {
                            float A0 = 0;
                            float A1 = 0;    //第三次转发是A1的次数
                            float A2 = 0;   //第三次转发是A2的次数
                            float A3 = 0;   //第三次转发是A2的次数
                            StringBuilder sb = new StringBuilder();
                            //遍历list容器中保存的路径,并且打印出来
                            for (int i = 0; i <= list.Count - 1; i++)
                            {
                                string str = "";
                                //遍历list中数组的数据
                                for (int j = 0; j <= n - 1; j++)
                                {
                                    str += list[i][j].ToString() + "----";
                                }
    
                                //计算第三次转发的次数
                                if (list[i][n - 1].ToString().Trim() == "0")
                                {
                                    A0 = A0 + 1;
                                }
                                if (list[i][n - 1].ToString().Trim() == "1")
                                {
                                    A1 = A1 + 1;
                                }
                                if (list[i][n - 1].ToString().Trim() == "2")
                                {
                                    A2 = A2 + 1;
                                }
                                if (list[i][n - 1].ToString().Trim() == "3")
                                {
                                    A3 = A3 + 1;
                                }
    
                                Console.WriteLine(str);
                                sb.AppendLine(str);
                            }
                            float A0per = A0 / list.Count;
                            float A1per = A1 / list.Count;
                            float A2per = A2 / list.Count;
                            float A3per = A3 / list.Count;
    
                            //把路径数据保存到文件中
                            File.WriteAllText("E:\result.txt", sb.ToString());
                            Console.WriteLine("传播谣言的总数:" + list.Count);
                            Console.WriteLine("A0收到第3次转发谣言的概率是:" + A0per * 100 + "%");
                            Console.WriteLine("A1收到第3次转发谣言的概率是:" + A1per * 100 + "%");
                            Console.WriteLine("A2收到第3次转发谣言的概率是:" + A2per * 100 + "%");
                            Console.WriteLine("A3收到第3次转发谣言的概率是:" + A3per * 100 + "%");
                            Console.WriteLine("A4--A9 收到第3次转发谣言的概率也是:" + A3per * 100 + "%");
                            Console.WriteLine("输出结束了,转发路径文件保存在E:\result.txt");
                            return;
                        }
                        catch (Exception ex)
                        {
                            throw;
                        }
                    }
                    else
                    {
                        for (int i = 0; i <= list.Count - 1; i++)
                        {
                            //获取list容器中数组的长度
                            int count = list[0].Length;
                            //获取上一个传播者
                            string a0 = list[i][n - 2].ToString();
                            //获取本次传播者
                            string a1 = list[i][n - 1].ToString();
                            for (int j = 0; j <= 9; j++)
                            {
                                //本次传播者不等于传给自己以及上一个传播者
                                if (j.ToString() != a0 && j.ToString() != a1)
                                {
                                    string[] s = new string[n + 1];
                                    for (int m = 0; m <= count - 1; m++)
                                    {
                                        s[m] = list[i][m].ToString();
                                    }
                                    //保存本次传播的人
                                    s[n] = j.ToString();
                                    //把数据放到list1容器中
                                    list1.Add(s);
                                }
    
                            }
                        }
                    }
                }
                n++;
                //递归
                Compulate(list1, n, k);
            }
        }
    }
  • 相关阅读:
    克如斯卡尔 P1546
    真正的spfa
    第四课 最小生成树 要点
    关于vscode中nullptr未定义
    cmake学习笔记
    python学习笔记
    (BFS 图的遍历) 2906. kotori和迷宫
    (图论基础题) leetcode 997. Find the Town Judge
    (BFS DFS 并查集) leetcode 547. Friend Circles
    (BFS DFS 图的遍历) leetcode 841. Keys and Rooms
  • 原文地址:https://www.cnblogs.com/luoyangcn/p/4859284.html
Copyright © 2020-2023  润新知