Javascript 用最少的浪费为k人切n块蛋糕
给定一个半径为n块蛋糕的数组,一个整数(k)表示您需要多少人(或切片),您可以从蛋糕上以最少的浪费切割出最大的面积是多少 数学不是我的强项,所以我很难精确地确定每次推导出正确面积所需的算法。我尝试过对半径进行排序,然后将最大面积除以2,直到它小于下一个面积,但这并不能给出一致的结果 这就是我所处的位置:Javascript 用最少的浪费为k人切n块蛋糕,javascript,algorithm,data-structures,Javascript,Algorithm,Data Structures,给定一个半径为n块蛋糕的数组,一个整数(k)表示您需要多少人(或切片),您可以从蛋糕上以最少的浪费切割出最大的面积是多少 数学不是我的强项,所以我很难精确地确定每次推导出正确面积所需的算法。我尝试过对半径进行排序,然后将最大面积除以2,直到它小于下一个面积,但这并不能给出一致的结果 这就是我所处的位置: // get areas of each cake const pi = 3.14159265359; let areas = []; let size; radii.so
// get areas of each cake
const pi = 3.14159265359;
let areas = [];
let size;
radii.sort(function(a, b){return a - b});
for (let i = 0; i < radii.length; i++) {
areas.push(pi * radii[i] * radii[i]);
}
// divide largest in half
for (let i = areas.length-1; i > 0; i--) {
if (areas[areas.length-1] / 2 < areas[i-1]) {
}
}
// if that number is smaller than the next smallest cake
// and you can get 6 equal pieces
// size = largest cake area / 2
// if you cannot get 6 equal pieces
// divide the largest cake area by 4
// check that that number can fit into the next cakes
// until there are 6 pieces - size = largest cake / 4
};```
input: [1,1,1,2,2,3],6
Expected output: 7.0686
input: [1,5],5
Expected output: 15.7079
//获取每个蛋糕的面积
常数pi=3.14159265359;
让面积=[];
让大小;
sort(函数(a,b){返回a-b});
对于(设i=0;i0;i--){
if(面积[面积长度-1]/2<面积[i-1]){
}
}
//如果这个数字小于下一个最小的蛋糕
//你可以得到6个相等的碎片
//尺寸=最大蛋糕面积/2
//如果你不能得到6个相等的碎片
//将最大蛋糕面积除以4
//检查这个数字是否适合下一个蛋糕
//直到有6块——尺寸=最大蛋糕/4块
};```
输入:[1,1,1,2,2,3],6
预期产出:7.0686
输入:[1,5],5
预期产出:15.7079
据我所知,每个人都只得到一块蛋糕,每个人的蛋糕都有相同的面积,剩余物要最小化,也就是说,蛋糕的大小要最大化。例如,在第二个例子中,大蛋糕被切成5块,小蛋糕被剩下
将蛋糕按大小分类,然后从1、2、3……中最大的蛋糕开始切片。。。碎片不一定会产生最佳结果。如果你有4块半径为4的蛋糕和1块半径为5的蛋糕供5个人食用,那么最佳的解决方案是给每个人一个半径为4的整块蛋糕或一块半径为5的蛋糕切成相同大小。但那块较大的蛋糕不会是一半,或三分之一,或。。。一块蛋糕
因此,将任何蛋糕切成任何数量的块都可以确定最佳尺寸。为了避免两次检查同一个解决方案,我们将首先创建一组大小(即,一个不带双精度的列表):
蛋糕和尺寸的排列顺序并不重要;不管怎样,我们都要试一下。对于每种尺寸,我们将计算蛋糕的面积,切成1,2,3。。。n块,其中n是人数(因为没有必要为6个人将蛋糕切成7块)
现在,对于每种大小的蛋糕,我们将迭代每个蛋糕的大小,并检查我们可以从每个蛋糕上切下多少块。当我们为每个人准备了足够的蛋糕块时,我们会记住这个蛋糕块的大小作为初始的最大尺寸,然后转到下一个尺寸的蛋糕。当我们检查了蛋糕的所有尺寸后,我们就会知道最佳尺寸是什么:
cake area: 3.1416 3.1416 3.1416 12.5664 12.5664 28.2743
3.1416 1 1 1 3 -> OK
12.5664 0 0 0 1 1 2
6.2832 0 0 0 2 2 4 -> OK
28.2743 0 0 0 0 0 1
14.1372 0 0 0 0 0 2
9.4248 0 0 0 1 1 3
7.0686 0 0 0 1 1 4 -> OK
因此,我们发现可以从现有蛋糕上切6次的最大块面积为7.0686
函数(半径,人){
设cakeSizes=radii.map(r=>r*r*Math.PI);
设maxSize=0;
新集合(cakeSizes).forEach(大小=>{
对于(让切片=1;切片(
numberOfSlices+数学地板(蛋糕/(大小/片))
),0)>=人){
maxSize=Math.max(maxSize,大小/切片);
打破
}
}
});
返回最大大小;
}
文件。写(1,1,1,2,2,3,6))代码>好的,我提出的解决方案基本上是一个贪婪算法,它跟踪每个蛋糕应该取多少片,然后在下一步尝试找出最好的蛋糕来添加一片
我用来判断哪种蛋糕最好的方法是问这样一个问题:如果我必须与其他蛋糕分享,哪种蛋糕可能有最大的一块?然后我会在蛋糕上加一片
除此之外,我们还需要跟踪最小切片大小,因为所有切片的大小都必须相等
不管怎样,这是算法。希望这有帮助!:)
函数findBiggestSlice(区域){
设指数=0
设最大切片=0
for(设i=0;i最大切片){
指数=i
最大切片=切片大小
}
}
回报指数
}
函数nCakesk切片(半径、切片){
//得到每个蛋糕的面积
常数pi=3.14159265359;
让面积=[];
设大小=无穷大;
sort(函数(a,b){返回a-b});
对于(设i=0;i
如何定义“废物”?请准确定义变量(切哪块蛋糕?),你需要最小化的数字,以及约束条件(每个k
人都得到相同数量的蛋糕,不管有多少块?)。即使数学不是你的强项,你应该看看“请不要在收到答案后故意破坏你的问题”。我们不仅仅是为你回答这个问题,它也可能对其他人有用。顺便说一句,这是由加州保利波莫纳(CPP)主办的2019年高中编程比赛(HSPC)中的一个问题,谢谢!我非常感谢您的回复,回答得很好。(我还没有找到一个最佳尺寸不是分区o的例子
size: 1
area: 3.1416
pieces: 3.1416, 1.5708, 1.0472, 0.7854, 0.6283, 0.5236
size: 2
area: 12.5664
pieces: 12.5664, 6.2832, 4.1888, 3.1416, 2.5133, 2.0944
size: 3
area: 28.2743
pieces: 28.2743, 14.1372, 9.4248, 7.0686, 5.6549, 4.7124
cake area: 3.1416 3.1416 3.1416 12.5664 12.5664 28.2743
3.1416 1 1 1 3 -> OK
12.5664 0 0 0 1 1 2
6.2832 0 0 0 2 2 4 -> OK
28.2743 0 0 0 0 0 1
14.1372 0 0 0 0 0 2
9.4248 0 0 0 1 1 3
7.0686 0 0 0 1 1 4 -> OK
function findBiggestSlice(areas){
let index = 0
let largestSlice = 0
for(let i = 0; i < areas.length; i++){
let sliceSize = areas[i].total/(areas[i].slices + 1)
if(sliceSize > largestSlice){
index = i
largestSlice = sliceSize
}
}
return index
}
function nCakeskSlices(radii, slices){
// get areas of each cake
const pi = 3.14159265359;
let areas = [];
let sliceSize = Infinity;
radii.sort(function(a, b){return a - b});
for (let i = 0; i < radii.length; i++) {
totalArea = pi * radii[i] * radii[i];
areas.push({
'total': totalArea,
'slices': 0,
});
}
for(let person = 0; person < slices; person++){
sliceCakeIndex = findBiggestSlice(areas)
areas[sliceCakeIndex].slices += 1;
newSliceSize = areas[sliceCakeIndex].total/(areas[sliceCakeIndex].slices)
sliceSize = Math.min(newSliceSize, sliceSize);
}
return sliceSize
};