算法问题:把一个数分成m个数,有且仅有一个最大数
今天写一个游戏的时候遇到了这么一个算法问题,因为觉得自己写的算法不是很好,又想不出其他解法,想来求助一下。
下面详细描述一下题目:
有一个整数n,分成m个整数(m个整数之和等于n),m个整数中有且仅有一个最大数且都不为0。返回一个组合即可,但是该组合应该是所有组合里随机的一个。
eg:
n=4,m=2, 分解后整数为 3,1
n=9,m=2, 分解后整数为 8,1或7,2或6,3或5,4
下面是我的代码(js):
function ran(nNum,mNum) {
var m = nNum - mNum + 1;
var n = nNum%mNum == 0?nNum/mNum+1:Math.ceil(nNum/mNum);
var bestNum = Math.floor(Math.random()*(m-n)+n);
var currentNum = 0;
var arrList = [];
arrList.push(bestNum);
currentNum+=bestNum;
for(var i=1;i<mNum;i++) {
if(i == mNum-1) {
var rad = nNum - currentNum;
if(rad == bestNum) {
} else {
arrList.push(rad);
}
} else {
var min = (nNum - currentNum) - (mNum-1-i)*(bestNum-1);
if(min<0) {
min = 1;
}
var max = bestNum-1;
if(nNum - currentNum - (mNum-1-i) < bestNum) {
max = nNum - currentNum - (mNum-1-i);
}
var rad = Math.round(Math.random()*(max-min))+min;
currentNum += rad;
if(currentNum>nNum) {
currentNum -= rad;
i--;
continue;
} else {
arrList.push(rad);
}
}
}
console.log(arrList);
}
个人算法能力薄弱,见谅
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
https://jsfiddle.net/hsfzxjy/aevc56ts/2/
其实并不是真正的随机,每种情况概率并不相等
---Update---
另一种实现,相对均匀: https://jsfiddle.net/hsfzxjy/f5r50zr4/4/
基本思路:将 n 分成 m 份,等价于 将 n 个球排成一排,在空隙中插入 m-1 个隔板
大概有个思路:
生成一组m个随机数,并只有一个最大数
取得这组数的和sum,然后n/sum得到比例s
再把这组数都乘以s并取整
问题在取整后总和可能会小于n,或者是最大值和次大值差值很小时取整后可能会相等
对这两个情况特殊处理一下就可以了
因为生成随机数时不用考虑n,在生成完成后再用比例去缩放数值,所以随机性应该还可以
代码晚点看情况补上
最大数max = n - m + 1
,剩下的都为1
,这样分可以吗?测试代码:
下面是某一次测试的结果:
先将n-1分隔成m个随机数,然后取其中最大值进行+1