递归算法

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);
        }
    }
}
原文地址:https://www.cnblogs.com/luoyangcn/p/4859284.html