Не понимаю, как правильно работает решение Codility CountDiv

124
17

Codility CountDiv Упражнение:

Учитывая диапазон A..B и значение K, верните количество значений в диапазоне, которые делятся на K.

Приведенный пример: A = 6, B = 11 и K = 2. В диапазоне от 6 до 11 числа, делящиеся на 2, равны 6, 8 и 10, поэтому ответ равен 3. Требуемое решение должно быть O (1) - поэтому необходим простой расчет.

Вы можете предположить, что A и B находятся в диапазоне 0..2.000.000.000, K 1..2.000.000.000 и что 0 <= A <= B.

Принятое решение, набравшее 100%, выглядит следующим образом:

int solution(int A, int B, int K)
{
int inclusive = ((A%K)==0) ? 1 : 0;
return (B/K) - (A/K) + inclusive;
}

Там, где я запутался в том, что когда я тестирую это решение со входами A = 0, B = 0 и K = 1, результат равен 1? Я бы подумал, что в диапазоне от 0 до 0 число значений, делящихся на 1, равно... 0!

Я думал, что это ошибка и что +1 для инклюзивных значений A должен быть установлен только в том случае, если A отличен от нуля.

Поэтому я представил следующее решение (проверьте, что A отличен от нуля):

int solution(int A, int B, int K)
{
int inclusive = (A && (A%K)==0) ? 1 : 0;
return (B/K) - (A/K) + inclusive;
}

Но это только набрало 62% (50% правильности и 75% производительности). Некоторыми из неудачных тестов были:

    A = 0, B = 1, K = 11 - Got 0, ожидаемый 1 A = 0, B = MAXINT, K в {1, MAXINT}, получено 2000000000, ожидается 2000000001

Может кто-нибудь объяснить?

спросил(а) 2016-07-06T02:34:00+03:00 4 года, 3 месяца назад
1
Решение
82

Значение 0 делится на K для всех K, которые разрешены (не равны нулю). Нет ничего особенного в отношении нуля. Определение делимых означает, что после деления нет остатка.

ответил(а) 2016-07-06T02:41:00+03:00 4 года, 3 месяца назад
72

Диапазон включительно: в диапазоне от 0 до 0 есть 1 значение: само значение 0. Все значения делятся на 1, поэтому результат действительно равен 1.

Обратите внимание, что предлагаемый код является избыточным:

int inclusive = ((A%K)==0)? 1: 0; эквивалентно int inclusive = (A%K)==0; , Его можно дополнительно упростить как int inclusive = !(A%K); и полное решение становится однострочным:

int solution(int A, int B, int K) { return B/K - A/K + !(A%K); }

И вот вариант с двумя дивизиями:

int solution(int A, int B, int K) { return B/K - (A ? (A-1)/K : -1); }

ответил(а) 2016-07-06T02:47:00+03:00 4 года, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема