В вашем коде есть как минимум 3 различных проблемы.
Вы пытаетесь вычислить количество комбинаций, используя факториалы. Проблема с факториалом в том, что он растет невероятно быстро: промежуточные результаты не попадают в диапазон для типа данных long
, и результат бесполезен. Вы можете использовать BigInteger
для вычислений, но это не будет особенно эффективно. С этим изменением:
public static long numPossibleTickets(int k, int n, int m) {
int i;
int j;
BigInteger numerator = BigInteger.valueOf(n);
BigInteger denominator = BigInteger.valueOf(k);
long total = 0;
for (i = n - 1; i > (k + 1); i--) {
numerator = numerator.multiply(BigInteger.valueOf(i));
}
i = 0;
for (j = k; j > 0; j--) {
denominator = denominator.multiply(denominator.subtract(BigInteger.valueOf(i)));
i++;
}
total = m * numerator.divide(denominator).longValue();
return total;
}
Во-вторых, l oop, вычисляющий числитель, отключен на единицу: вместо вычисления 69! / 5! это вычисление 69! / 6 !. К счастью, это легко исправить:
for (i = n - 1; i >= (k + 1); i--) {
numerator = numerator.multiply(BigInteger.valueOf(i));
}
В-третьих, l oop, который вычисляет знаменатель, кажется, далек от истины. Я не знаю, что вы пытаетесь сделать, но с учетом того, что вы вычисляете для числителя, знаменатель должен быть вычислением (nk) !, и это может выглядеть так:
BigInteger denominator = BigInteger.ONE;
for (int j = n-k; j > 1; j--) {
denominator = denominator.multiply(BigInteger.valueOf(j));
}
With эти три изменения, я получаю ожидаемый результат 292201338
.