题
我正在尝试计算帕斯卡三角形第 100 行中的特定条目是否可被 3 整除。我使用公式 nCr 计算此值,其中 n=100,r 是第 100 行中的不同条目。我使用下面的代码来计算组合
public static double Combination(int n, int m, double comb)
{
for (int r = -1; ++r < m; )
comb = comb * (n - r) / (r + 1);
return comb;
}
但对于 100C16 这样的值,我得到的数字很大,其中包含小数和 e。我在网上搜索发现实际上有12个数字不能被3整除,但是我的程序在第100行给了我63个不能被3整除的数字,这是错误的。谁能告诉我我是什么做错事。
解决方案
我假设“NCR”是N-Splect-R的速写,或从n,右边选择r? 要查看NCR是否已被三个划分,您无需计算结果,您只需弄清楚它是否已被拆除为3.您必须看到多少次n!是可被3的,然后是多少次!已被3个分开,多少次(n-r)!是。
真的很简单 - 1!不可分割的3,2!不是,3!是可分开的一次。 4!和5!也可被占用一次。 6!是可分的两次,所以7!和8! 9!是可分开的4次,等等。一直到N到N(或在不计算出逐步计算的情况下,这并不是那么难),并检查。
澄清 - 我的数学研究在希伯来语中,所以“多次n!可被3送3”,可能不是正确的英语方式。通过“n!可被3米即将其分开”,我的意思是生成的,其中k根本不可分割。
编辑:一个例子。让我们看看10c4是否已被3划分为3.
让我们做一个小桌子说多少次k!已被3分开(K!列只是用于演示,在计算DIVISIBLITY列时实际上不需要它):
k k! Divisibility
1 1 0
2 2 0
3 6 1
4 24 1
5 120 1
6 720 2
7 5040 2
8 40320 2
9 362880 4
10 3628800 4
.
10c4是10! /(6!* 4!)。
10!是可分的4次(意思是10!= 3 ^ 4 *不可分割的3), 6!是可分开的2次 4!是可分割的1次
所以10! (6!* 4!)可被3划破3.事实上3 * 70。
其他提示
首先,你使用的是双打,我认为这不是一个好主意。浮点数过一段时间就会出错。
如果数量不会增长那么大,可以使用以下方法:
public static long nCr (int m, int n) {
long tmp = 1;
int j = 2;
int k = m-n;
for(int i = m; i > k; i--) {
tmp *= i;
while(j <= n && tmp%j == 0) {
tmp /= j++;
}
}
while(j <= n) {
tmp /= j++;
}
return tmp;
}
然而在这种情况下,这仍然不够。在这种情况下,人们可以使用 BigInteger
结构体 System.Numerics
public static BigInteger nCr (int m, int n) {
BigInteger tmp = 1;
int j = 2;
int k = m-n;
for(int i = m; i > k; i--) {
tmp *= i;
while(j <= n && tmp%j == 0) {
tmp /= j++;
}
}
while(j <= n) {
tmp /= j++;
}
return tmp;
}
您可能会说,使用 BigInteger 不需要交错除法和乘法。但是,如果 BigInteger 相当大,则对数据的操作将花费一些时间(因为该数字表示为多个字节的数组)。通过保持较小的值可以避免较长的计算时间。