例如 一个数字100,怎么把100随机分成一个数组,并且这个数组里的和是100,并且这个数组里的每个数字差都不会太大,比如100拆成10,20,15,20,5,30。数组和一定是int类型。求解。
设数字为N,和的范围为1-N。
1-N之间是若干节点(位置),假设为a,b,c。
线的长度是N,N的长度=各个线段的和
也就是N=(N-c)+(c-b)+(b-a)+(a-0);
SO,可以得出a,b,c就是你要的三个数。
同理,你可以根据自己的需要改成a...n-1个节点,可以是三个数,也可以是四个数,可以随机出一个1至(n-1)的数
“每个数字差都不会太大”,这个就得另外写逻辑了,做减法判断差,如果超过你的指定值,重新随机,如此循环xx下(或者根据XX下选择差最小的那组)
线段的长度应该是0-n 哈,是从0开始的,我画图的时候没注意 这样: 0_____a___b____c___n
@七芯海棠: 大神,看起来思路应该是这样的,尴尬的是我有点蒙。
static void Main(string[] args) { List<int> resultList = new List<int>(); int curr = 100;// int index = 3;//节点个数(3个节点会生成4条线段,也就是4个值) List<int> list = new List<int>(); for (int i = 0; i < index; i++) { Random r = new Random(); int v = r.Next(100); do { //产生不重复的随机数 v = r.Next(100); } while (list.Contains(v)); list.Add(v); } list.Sort(); //输出最后一条线段 Console.WriteLine(curr-list[list.Count-1]); for (int i = list.Count-1; i >=1; i--) { //输出中间线段 Console.WriteLine(list[i] - list[i-1]); } //输出第一条线段 Console.WriteLine(list[0]-0); }
@七芯海棠: 谢谢,已解决
@七芯海棠: 刚刚认真测试了下你的这个方法,其实还是有一点缺陷,有时候分的很平均,但是有时候各个数之间相差也很大,
我的最终解决方法
static void Main(string[] args)
{
Random random = new Random();
var intList = new List<int>();
var oldmutil =100;
var mutil = 100;
while (mutil > 0)
{
var num = random.Next(1, mutil);
if (oldmutil < 10)
{
intList.Add(num == 0 ? 1 : num);
if (mutil == 1) break;
mutil -= num;
}
else
{
if (num <= oldmutil / 10)
{
intList.Add(num == 0 ? 1 : num);
if (mutil == 1) break;
mutil -= num;
}
}
}
foreach (var item in intList)
{
Console.WriteLine(item);
}
}
@如此拉风的女人:
static void Main(string[] args) { Random random = new Random(); var intList = new List<int>(); int mutil = 100; int du = 10; do { int index = random.Next(1, du); if (index > 0) { intList.Add(index); } } while (!(intList.Sum() >= mutil - du)); intList.Add(mutil - intList.Sum()); foreach (var item in intList) { Console.WriteLine(item); } Console.WriteLine("集合值:"+intList.Sum()); }
看了你的最终方案我重新写了下 做了一些精简 O(∩_∩)O
@七芯海棠: 可以,这很强势,不过如果mutil =100改成1000就要改du的值。不是很好
@如此拉风的女人: du=mutil/10 可以把du的值取成mutil的十分之一,不过mutil大了,du值也变大的话,值之间的差也会变大的,du值不随着mutil变大的话生成的数的个数又居多,基于目前的逻辑两者不太好协调,只能基于实际情况互相折中了
@七芯海棠: 恩恩
@-小确幸:
这一段代码永远不会进入,是多余的吗?然后好像还不能控制随机的数量
if (oldmutil < 10)
{
intList.Add(num == 0 ? 1 : num);
if (mutil == 1) break;
mutil -= num;
}
抱歉,过了这么长时间打扰到你,我最近就是想碰到了相关的问题,游戏中怪物掉落的金钱数量是固定的,然后怪物死亡后会掉落3~5枚金币,我需要将金币总价值随机分配给打比方5枚金币,这5枚金币玩家拾取得到的总价值就等于怪物的金钱数量,这也就需要我可以控制随机出来的数量
创建集合;
随机0-100取数,插入集合;
判断是否小于100,是重复上步操作;
等于100直接结束;
大于100剔除最后那个数,直接凑一个数上去结束;
谢谢,我试过,不满足条件
@如此拉风的女人: 那是你代码没写好三,逻辑是满足的。
其实可以创建一个集合,然后随机生成一个数0-100之间的数,如果是100以内的,加入到集合中,再把那个0-100换成100-生成的数,依次往复,直到最后数为0 。那个集合就是所需要的集合(可以将生成的随机数转换为整数)
看看我写的代码,你可以随便输入要拆分的数字。然后就会生成。
@鸿燕藏锋: 像你这种就不行了,8和2差太大。43和6和1差太大。要求就是这些数组相差不能太大,
@如此拉风的女人: 的确是存在这种问题。那么对于产生随机数如何进行进行控制随机呢
@鸿燕藏锋: 不过还是谢谢你哦
@如此拉风的女人: 没事,我写的时候也感觉存在这种问题,那么知道如何解决吗?这就是产生随机数的时候没有想象中的那么随机,它是靠近那个自己输入的值的
@鸿燕藏锋: 你看我楼上那个大神写的就知道了,他代码都贴出来了。思路就是那样的,
@如此拉风的女人: OK