• 递归算法


    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);
            }
        }
    }
  • 相关阅读:
    3-为什么很多 对 1e9+7(100000007)取模
    6-关于#include<bits/stdc++.h>
    7-n!的位数(斯特灵公式)
    5-math中函数汇总
    6-找数的倍数
    6-Collision-hdu5114(小球碰撞)
    5-青蛙的约会(ex_gcd)
    4-圆数Round Numbers(数位dp)
    4-memset函数总结
    一种Furture模式处理请求中循环独立的任务的方法
  • 原文地址:https://www.cnblogs.com/luoyangcn/p/4859284.html
Copyright © 2020-2023  润新知