我们彼此堆叠的箱子数量不受限制。
p =第一个堆栈的大小
每个堆栈比之前的堆栈大“ k”。
For example: p=3 k=2
1,2,3
4,5,6,7,8
9,10,11,12,13,14,15
现在的任务是移动用户定义的一个盒子,并计算要移动该特定盒子必须在其上方移动多少个盒子。用户将继续插入变量d中定义的天数的盒子。
因此输入将如下所示:
p=3 k=2 d=3(3 days aka 3 boxes to move)
5 (Box 5)
3
12
输出为:6 ....为什么?因为它必须移动3个框才能得到框5,框3的框是0,框12的框是3。
希望您理解了这个概念,但是我一直在努力将所有这些正确地放入代码中。我在作业的某些方面取得了成功,但似乎无法正常工作。
它正确地给了我一系列的盒子...但是当我输入数字时并不能正确地计算....该数字是(在哪个堆栈中),哪个是该堆栈的顶部数字,所以程序会替换它,并获取必须移动的盒子数。
希望您能帮助我解决我做错的事情和应该做的事情。
这是我尝试的但似乎无法正常工作的代码:
import java.util.Scanner;
public class A1 {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int p = sc.nextInt();
int k = sc.nextInt();
int d = sc.nextInt();
int base = 1;
int size = p;
int topNum = p+(p+k);
int e=0;
int numBox = 0;
int movedBox=0;
int counter = 0;
while(e<d) {
numBox = sc.nextInt();
e++;
base=base+size;
size=size+k;
topNum=topNum+(size+k);
movedBox=topNum-numBox;
counter=movedBox+counter;
}
System.out.println(counter);
}
}
更新后的版本:
import java.util.Scanner;
public class SO {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int p = sc.nextInt();
int k = sc.nextInt();
int d = sc.nextInt();
int height = p;
int topNum = p;
int e=0;
int numBox = 0;
int movedBox=0;
int counter = 0;
while(e<d) {
numBox = sc.nextInt();
e++;
while(topNum<numBox) {
height=height+k;
topNum = topNum + height;
}
movedBox=topNum-numBox;
counter=movedBox+counter;
}
System.out.println(counter);
}
}
最佳答案
首先,您犯的最大错误是在循环中添加变量而不先重置变量。
这是为什么?在循环的第一次迭代中,您可以根据在框外进行的初始化来获取正确的数字。但是,在第二个循环中,已经为第一个移动的框调整了数字(应该是)。但是现在我们从前面的堆栈中移出一个盒子,然后将第一个移动中的数字添加到该盒子中。因此,如果您在第一个计算中(框5)的topNum
为8,则现在将其添加!如果它大于8,则肯定不是框3的正确topNum
。
在每次迭代之间应增加的唯一变量是counter
。其他所有每次都需要重置。
但是给定一个盒号,您可能希望通过循环来计算堆栈:从p开始,然后添加p + k个数字并检查它是否是正确的堆栈,如果不是,则添加另一个p + 2k个数字,等等。环。
我认为您太混乱了。每次从第一个堆栈开始,应该有一个外循环来获取数字,并有一个内循环来计算堆栈。
所以数学是:
我们注意到堆栈号n
的大小始终为p +(n-1)×k。第一个是3,第二个是5,第三个是7盒子高。
我们还注意到,每个堆栈以一个数字结尾是其自身高度与前一个高度的总和。
topNumber = p +(p + k)+(p + 2k)...(p +(n-1)×k)
对于n=1
,它将为p
(3)。对于n=2
,这将是2p+2
(8),对于n=3
,这将是3p+k+2k
,这是9+2+4
(15)。
因此,对于给定为numBox
的单个纸箱编号,您可以执行以下操作:
int topNumber = p;
int height = p;
while ( topNumber < numBox ) {
height += k;
topNumber += height;
}
movedBoxes = topNumber - numBox;
(以防万一,您还不知道,
x += y
与x = x + y
相同)。所以你看,你快要到了。
您不应该在
base
中添加任何内容,因为您没有使用它。实际上,如果您有一个仅分配给变量而从未实际使用过的变量,则根本不需要它。您正在将
k
添加到您的size
(我的height
)中,这很好。但是,您要在下一行添加另一个k
,这意味着它实际上是以前的大小+ 2k。您忘记了已经在该变量中添加了k
,所以它已经是最新的了。您认为一个循环可以处理检索新数字并计算其
movedBoxes
的情况。不能一圈完成。您需要为每个数字分别执行任务,并且任务本身处于循环中,因此您需要在循环内部进行循环。请务必始终从p
重新开始编号。上面的方法是解决这个问题的幼稚方法。如您所见,对于非常大的数字,它的运行速度非常慢,因为它实际上一直在搜索该数字在堆栈中的第一个
n
。实际上,有一种无需循环即可解决的方法(当然,除了按天读取数字的循环外)。但这需要一些数学运算。如前所述,第n个堆栈的最高数tₙ实际上是:
也就是说:
,
将高斯规则应用于算术级数:
现在,这是一个方程式。而且,如果我们知道堆栈的最高编号是多少,我们可以将其求解为n。也就是说,如果您有一个顶数tₙ,则可以通过求解二次方程式找到
n
:当然,您只需要此方程的正根,因此:
简化为:
但是我们不一定有最高人数,对吗?但是,对于给定的数字
t
,我们知道它大于上一个堆栈的顶部数字,并且不大于其自身堆栈的顶部数字:这意味着,如果我们对此t求解二次方程,结果将是一个实数(不是整数!)
s
这样:也就是说,如果将其四舍五入,将得到它所在的堆栈的n,然后可以根据上面的tₙ公式计算出实际的tₙ。
现在,回到编程:
您是否学会了如何创建方法?如果是这样,我建议将tₙ和
n
的公式放在单独的方法中,以使代码清晰。用整数计算除法时,必须非常小心。 tₙ的公式正确,因为分数将始终产生适当的整数。但是,如果您不确定分区是
n
分区而不是double
分区,则integer
的公式将不正确。没关系平方根。如果在方法中定义它,则将参数作为double
传递。如果不是,请确保将k除以2.0
而不是2
,k²除以4.0
而不是4
,将大部分除以(double)k
而不是k
。记住将结果四舍五入。如果您只写
(int)
,它将被四舍五入。注意除以零。输入
k
的值时,请确保它不为零。
关于java - 堆叠盒分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26874072/