还是风的那个方法。 先取第一个随机数你n1 = R(0~301); 然后取 n2 = R(0~(301-n1))  .....最后来个乱序。

解决方案 »

  1.   


                int w = 301;
                Random random = new Random();
                for (int r = 0; r < 27; r++)
                {
                    int x = random.Next(w / (27 - r));
                    w -= x;
                    Console.WriteLine(x);
                }
    输出:
    0
    6
    6
    10
    8
    1
    2
    4
    3
    9
    3
    5
    6
    2
    17
    4
    7
    9
    3
    7
    19
    4
    3
    17
    0
    46
    13
      

  2.   

    错了,无视之。
    不过只要处理一下最后以为就可以变正确了。
                int w = 301;
                Random random = new Random();
                for (int r = 0; r < 27; r++)
                {
                    int w2 = 0;
                    if (r != 26)
                        w2 = w / (27 - r);
                    else
                        w2 = w;
                    int x = random.Next(w2);
                    w -= x;
                    Console.WriteLine(x);
                }
      

  3.   


    暂时将震荡值设置为平均值的一半         static int[] GetRandomNumbers(int count, int total)
            {
                //平均值
                int avg = total / count;
                //设震荡区间为平均值的一半
                int range = avg / 2;
                int[] arr = new int[count];
                Random ran = new Random();
                //将数组元素先设成平均值
                for (int i = 0; i < arr.Length; ++i)
                {
                    arr[i] = avg;
                }
                //随机获取2个数组元素,一个加上震荡值,一个减去震荡值
                for (int i = 0; i < arr.Length; ++i)
                {
                    int index = ran.Next(arr.Length);
                    if (i != index)
                    {
                        int add = ran.Next(range) + 1;
                        //不能减成负的
                        if (arr[index] - add >= 0)
                        {
                            arr[i] += add;
                            arr[index] -= add;
                        }
                    }
                }
                //修正数组元素,因为平均值很可能不是由整除得到的。
                int last = total - avg * count;
                for (int i = 0; i < last; ++i)
                {
                    int index = ran.Next(arr.Length);
                    arr[index] += 1;
                }
                return arr;
            }
      

  4.   


     int m = 301;//总数
                int n = 27;//个数            Random random = new Random();
                int x = 0;
               // int sum = 0; //用来验证和是否正确。 
                int[] arr = new int[n];  //用来保存结果
              
                for (int i = 0; i < n; i++)
                {                if (i!=n-1)
                    { 
                        int avg = m /(n-i);//动态平均值 ,为余下的总数/余下组数
                        x = random.Next(avg * 2); //生成随机数 震荡范围为 0 ~ 平均值*2
                        m -= x; //总数中减去已生成数
                    } 
                    else
                    {
                        x= m;
                    }
                   // sum += x;                arr[i] = x;
                }
      

  5.   

    不写代码,只说思路假设一根线段,总长N米,平均分成m段,这样有首位m+1个点然后随机把点左/右移动即可,最后计算两点间隔因为总长已经固定,无论你怎么移动点,结果都是一样如果你说要平均,我们只需设置一个合理的移动阀值,让他不至于偏离这个平均线段太远就ok
      

  6.   

      int Sum = 301;
                int Count = 27;
                int[] ary = new int[Count];
                for (int i = 0; i < Count; i++)
                    ary[i] = Sum / Count;
                Random r = new Random();
                for (int i = 0; i < Sum % Count; i++)
                    ary[r.Next(Count)]++;
                for (int i = 0; i < 800; i++)
                {
                    int a = r.Next(Count);
                    int b = r.Next(Count);
                    if (a != b && ary[a] > 0 && ary[b] > 0)
                    {
                        ary[a]--;
                        ary[b]++;
                    }
                }
                ary.ToList().ForEach(t => Console.Write(t + "   "));
                Console.ReadLine();
      

  7.   

    使用迭代法,逐个生成n个随机数,并逐个累加,
    如果小于m,继续迭代
    如果大于m,重新开始迭代
    如果等于m,输出随机数列表
      

  8.   

    先生成一个0~301的随机数a,在生成一个0~(301-a)的随机数b,再生成0~(301-a-b)的随机数c。
    循环,执行;不够的补0。
      

  9.   

    两个条件:27个数 & 和等于301
      

  10.   

    太easy了,把301个1随机加进27个起始值为0的数组里就行了。using System;namespace RandomGenerator
    {
        class Program
        {
            const int SUM = 301;
            const int SIZE = 27;        static void Main(string[] args)
            {           
                int[] numberArray = new int[SIZE];
                Array.Clear(numberArray, 0, numberArray.Length);
                int seed = (int)DateTime.Now.Ticks;
                Random random = new Random(seed);            for (int i = 0; i < SUM; i++)
                {
                    int index = random.Next(0, SIZE);
                    numberArray[index]++;
                }            int total = 0;
                for (int i = 0; i < SIZE; i++)
                {
                    total += numberArray[i];
                    Console.Write("{0} ", numberArray[i]);
                }
                Console.WriteLine();
                Console.WriteLine("Total: {0}", total);        }
        }
    }
      

  11.   

    下面这个改进的算法,利用平均值原理,可以减少循环圈。这样的话,即使总合和数组很大,也能很快算出来。using System;namespace RandomGenerator
    {
        class Program
        {
            const int SUM = 300001;
            const int SIZE = 270;        static void Main(string[] args)
            {           
                int[] numberArray = new int[SIZE];
                Array.Clear(numberArray, 0, numberArray.Length);
                int seed = (int)DateTime.Now.Ticks;
                Random random = new Random(seed);            int remainder = SUM;
                int iter = 0;
                while (remainder > 0)
                {
                    int average = remainder / SIZE;
                    if (average == 0)
                    {
                        average = 1;
                    }
                    int index = random.Next(0, SIZE);
                    numberArray[index] += average;
                    remainder -= average;
                    //Console.WriteLine("remainder: {0}, average: {1}", remainder, average);
                    iter++;
                }            Console.WriteLine("Loop size: {0}", iter);
                int total = 0;
                for (int i = 0; i < SIZE; i++)
                {
                    total += numberArray[i];
                    Console.Write("{0} ", numberArray[i]);
                }
                Console.WriteLine("Total: {0}", total);
            }
        }
    }
      

  12.   

    是不是和下面的有点像:
    一次循环:
    先生成第一个,和301比较,如果<301,继续生成,...直到第m个数,m<27且1+...+m>301时,此次循环结束
    生成第二个:....
    可能效率上比较慢吧,一直在比较...