Как найти количество кратных чисел в промежутке

Описание задачи

Данная программа должна вывести все числа в заданном диапазоне, которые делились бы без остатка на определенное число.

Решение задачи

  1. На вход принимаются два числа, которые задают диапазон и записываются в разные переменные.
  2. Также принимается число, которое будет делителем.
  3. Используем цикл for, чтобы пройтись по всему диапазону и проверить все числа на кратность. Выводим только те числа, которые делятся на заданное число без остатка.
  4. Конец.

Исходный код

Ниже дан исходный код для вывода всех чисел из заданного диапазона, которые удовлетворяют условию делимости на данное число. Результаты работы программы также даны ниже.

lower = int(input("Введите нижнюю границу диапазона:"))
upper = int(input("Введите верхнюю границу диапазона:"))
n = int(input("Введите делитель:"))
for i in range(lower, upper + 1):
    if(i % n == 0):
        print(i)

Объяснение работы программы

  1. Пользователь вводит два числа, нижнюю и верхнюю границы. Они записываются в отдельные переменные.
  2. Далее пользователь вводит число, которое будет делителем. Оно также сохраняется в своей переменной.
  3. Значение переменной цикла for варьируется от нижней до верхней границы с шагом 1.
  4. В процессе работы цикла проверяется, равен ли остаток от деления нулю. Если остаток равен нулю, делимое выводится на экран.
  5. Конец.

Результаты работы программы

Пример 1:
Введите нижнюю границу диапазона:1
Введите верхнюю границу диапазона:50
Введите делитель:5
5
10
15
20
25
30
35
40
45
50
 
Пример 2:
Введите нижнюю границу диапазона:50
Введите верхнюю границу диапазона:100
Введите делитель:7
56
63
70
77
84
91
98

Формулировка задачи:

Задача

Найдите количество чисел кратных k в отрезке [a, b]. Другими словами, вам нужно найти количество целых чисел x таких, что a ≤ x ≤ b и x делится на k.

Входные данные

В единственной строке входных данных находится три целых числа k, a, b (1 ≤ k ≤ 10^9; - 1018 ≤ a ≤ b ≤ 10^9).

Выходные данные

Выведите ответ на задачу.

Вопрос

Как пройти 57 тест программы?Никак не пойму.Я уже даже в строке #8 написал фигню, но это всё равно не работает :. Не понимаю, как обойти эти ошибки исполнения.

Код:

var
a,b,x:Int64;
k:byte;
begin
read(k,a,b);
 
if ((k=1) and(a<0))  then x:=abs(a)+abs(b);
if (a=-1000000000000000000) and (b= 1000000000000000000) then x:=b*2;
if ((a=0) and (b=0)) then x:=1
else
while (a<=b) do
    begin
    if (a mod k =0) then inc (x);
    inc(a);
    end;
writeln(x);
end.

Ввод:

1 -1000000000000000000 1000000000000000000

Вывод:

Ошибка выполнения [TIME_LIMIT_EXCEEDED]

Ошибка исполнения, код возврата -1
=====
Использовано: 10000 мс, 0 КБ

Код к задаче: «Найдите количество чисел кратных k в отрезке»

textual

var k, a, b, x: Int64;
begin
  read(k, a, b);
  if a >= 0 then a := a + k - 1;
  a := a - a mod k;
  if b < 0 then b := b - k + 1;
  b := b - b mod k;
  x := ((b - a) div k) + 1;
  write(x)
end.

Полезно ли:

5   голосов , оценка 3.800 из 5

Просмотров 2.3к. Обновлено 15 октября 2021

В диапазоне натуральных чисел от 2 до 99 определить, сколько из них кратны любому из чисел в диапазоне от 2 до 9.

Необходимо проверить кратность каждого числа сначала числу 2, потом 3 и т.д. до 9 включительно. Введем массив с восьмью ячейками. В первую будем записывать количество чисел кратных 2, во вторую — 3 и т.д.

  1. Записать в ячейки массива нули.
  2. Перебирая числа от 2 до 99,
    1. для каждого из них в цикле от 2 до 9
      1. проверять кратность числа внешнего цикла числу внутреннего.
      2. Если второе число делит нацело первое, значит увеличивать на 1 значение в соответствующей ячейке массива.
  3. Вывести индексы и соответствующие им значения из массива.

Pascal

найти количество кратных чисел паскаль


var
a: array[2..9] of byte;
i,j: byte;
begin
for i:=2 to 9 do a[i] := 0;
for i:=2 to 99 do
for j:=2 to 9 do
if i mod j = 0 then
a[j] := a[j] + 1;
for i:=2 to 9 do
writeln(i,' - ', a[i]);
end



2 - 49
3 - 33
4 - 24
5 - 19
6 - 16
7 - 14
8 - 12
9 - 11

Язык Си


#include
main() {
int a[8], i, j;
for (i=0; i<9; i++) a[i] = 0;
for (i=2; i<100; i++)
for (j=2; j<10; j++)
if (i%j == 0) a[j-2] += 1;
for (i=0; i<8; i++)
printf("%d - %dn", i+2, a[i]);
}

Python

найти количество кратных чисел Python


a = [0]*8
for i in range(2,100):
for j in range(2,10):
if i%j == 0:
a[j-2] += 1
i = 0
while i < len(a):
print(i+2, ' - ', a[i])
i += 1



2 - 49
3 - 33
4 - 24
5 - 19
6 - 16
7 - 14
8 - 12
9 - 11

КуМир


алг кратность
нач
цел таб a[2:9]
цел j,i
нц для i от 2 до 9
a[i] := 0
кц
нц для j от 2 до 99
нц для i от 2 до 9
если mod(j,i) = 0 то a[i]:=a[i]+1 все
кц
кц
нц для i от 2 до 9
вывод i, " - ", a[i], нс
кц
кон

Basic-256


dim a(8)
for i=2 to 99
for j=2 to 9
if i%j = 0 then
a[j-2] = a[j-2] + 1
endif
next j
next i

for i=0 to 7
print (i+2) + " - " + a[i]
next i

Кратные числа, калькулятор

Кратное число – это число, делащееся на данное целое число без остатка; например 12 кратно 3.

Найти, вычислить кратные с калькулятором

Кратное – это произведение целого числа на любое другое целое число. Например, первые шесть чисел, кратных 3: 3, 6, 9, 12, 15 и 18. Это легко проверить на примерах ниже:

3 x 1 = 3 ;

3 x 2 = 6 ;

3 x 3 = 9 ;

3 x 4 = 12 ;

3 x 5 = 15 ;

3 x 6 = 18.

Два и более чисел могут иметь общие кратные. Например, наименьшее общее кратное (НОК) 3 и 7 равно 21, т. е. произведению этих двух чисел.

Наглядная таблица чисел кратных 3

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • – Кратные 3

У меня есть три числа x, y, z.

Для диапазона между числами x и y.

Как найти общие числа,% которых с z равно 0, то есть сколько чисел между x и y делятся на z?

4b9b3361

Ответ 1

Это можно сделать в O (1): найти первую, найти последнюю, найти счетчик всех остальных.

Я предполагаю, что диапазон включен. Если ваши диапазоны являются эксклюзивными, настройте границы на единицу:

  • найдите первое значение после x, которое делится на z. Вы можете отказаться от x:

    x_mod = x % z;
    
    if(x_mod != 0)
      x += (z - x_mod);
    
  • найдите последнее значение до y, которое делится на y. Вы можете отменить y:

    y -= y % z;
    
  • найдите размер этого диапазона:

    if(x > y)
      return 0;
    else
      return (y - x) / z + 1;
    

Если доступны математические функции floor и ceil, первые две части могут быть написаны более читаемо. Также последнюю часть можно сжать с помощью математических функций:

 x = ceil  (x, z);
 y = floor (y, z);
 return max((y - x) / z + 1, 0);

если вход гарантированно является допустимым диапазоном (x >= y), последний тест или max не является обязательным:

 x = ceil  (x, z);
 y = floor (y, z);
 return (y - x) / z + 1;

Ответ 2

(2017, ответ переписан благодаря комментариям)
Число кратных z в числе n просто n / z

/ является целым делением, что означает десятичные знаки, которые могут возникнуть в результате деления, просто игнорируются (например, 17/5 => 3, а не 3.4).

Теперь, в диапазоне от x до y, сколько кратных z есть?

Посмотрим, сколько множителей m мы имеем до y

0----------------------------------x------------------------y
-m---m---m---m---m---m---m---m---m---m---m---m---m---m---m---

Вы видите, куда я иду… чтобы получить число кратных в диапазоне [ x, y ], получить число кратных y, а затем вычесть число кратных до x, (x-1) / z

Решение: ( y / z ) - (( x - 1 ) / z )


Программно, вы можете сделать функцию numberOfMultiples

function numberOfMultiples(n, z) {
   return n / z;
}

чтобы получить число кратных значений в диапазоне [x, y]

numberOfMultiples(y) - numberOfMultiples(x-1)

Функция O (1), нет необходимости в цикле, чтобы получить число кратных.

Примеры результатов, которые вы должны найти

  • [30, 90] ÷ 13 => 4
  • [1, 1000] ÷ 6 => 166
  • [100, 1000000] ÷ 7 => 142843
  • [777, 777777777] ÷ 7 => 111111001

В первом примере 90 / 13 = 6, (30-1) / 13 = 2 и 6-2 = 4

---26---39---52---65---78---91--
     ^                      ^
     30<---(4 multiples)-->90

Ответ 3

Я также столкнулся с этим на Codility. Мне потребовалось гораздо больше времени, чем мне хотелось бы признаться, чтобы придумать хорошее решение, поэтому я решил, что поделюсь тем, что я считаю элегантным решением!

Прямой подход 1/2:

O (N) временное решение с циклом и счетчиком, нереально, когда N = 2 млрд.

Удивительный подход 3:

Нам нужно количество цифр в некотором диапазоне, которые делятся на K.

Простой случай: предположим, диапазон [0.. n * K], N = n * K

N/K представляет количество цифр в [0, N), которые делятся на K, учитывая, что N% K = 0 (иначе, N делится на K)

ех. N = 9, K = 3, Num цифр = | {0 3 6} | = 3 = 9/3

Аналогичным образом,

N/K + 1 представляет количество цифр в [0, N], делимое на K

ех. N = 9, K = 3, Num цифр = | {0 3 6 9} | = 4 = 9/3 + 1

Я думаю, что понимание вышеизложенного факта – самая сложная часть этого вопроса, я не могу точно объяснить, почему он работает. Остальное сводится к сумме префиксов и обработке особых случаев.


Теперь у нас не всегда есть диапазон, который начинается с 0, и мы не можем предполагать, что две границы будут делиться на K. Но ждать! Мы можем исправить это, вычислив наши собственные хорошие верхние и нижние границы и используя некоторую магию вычитания 🙂

  1. Сначала найдите самые близкие верх и низ в диапазоне [A, B], которые делятся на K.

    • Верхняя граница (легче): напр. B = 10, K = 3, new_B = 9… шаблон B – B% K
    • Нижняя граница: отл. A = 10, K = 3, new_A = 12… попробуйте еще немного, и вы увидите, что шаблон A – A% K + K
  2. Затем рассчитайте следующее, используя вышеописанную технику:

    • Определите общее количество цифр X между [0, B], которые делятся на K
    • Определите общее количество цифр Y между [0, A), которые делятся на K
  3. Рассчитайте количество цифр между [A, B], которые делятся на K в постоянное время по выражению X – Y

Веб-сайт: https://codility.com/demo/take-sample-test/count_div/

class CountDiv {
    public int solution(int A, int B, int K) {
        int firstDivisible = A%K == 0 ? A : A + (K - A%K);
        int lastDivisible = B%K == 0 ? B : B - B%K; //B/K behaves this way by default.
        return (lastDivisible - firstDivisible)/K + 1;
    }
}

Я впервые объясняю такой подход. Обратная связь очень ценится 🙂

Ответ 4

Это один из вопросов урока Codility Lesson 3. По этому вопросу вход гарантированно находится в допустимом диапазоне. Я ответил на него с помощью Javascript:

function solution(x, y, z) {
    var totalDivisibles =  Math.floor(y / z),
        excludeDivisibles = Math.floor((x - 1) / z),
        divisiblesInArray = totalDivisibles - excludeDivisibles;
   return divisiblesInArray;
}

https://codility.com/demo/results/demoQX3MJC-8AP/

(Я действительно хотел спросить о некоторых других комментариях на этой странице, но пока у меня недостаточно очков повторения).

Ответ 5

Разделите y-x на z, округляя вниз. Добавьте один, если y%z < x%z или if x%z == 0.

Нет математического доказательства, если кто-то не заботится о предоставлении одного, но тестовых примеров, в Perl:

#!perl
use strict;
use warnings;
use Test::More;

sub multiples_in_range {
  my ($x, $y, $z) = @_;
  return 0 if $x > $y;
  my $ret = int( ($y - $x) / $z);
  $ret++ if $y%$z < $x%$z or $x%$z == 0;
  return $ret;
}   

for my $z (2 .. 10) {
  for my $x (0 .. 2*$z) {
    for my $y (0 .. 4*$z) {
      is multiples_in_range($x, $y, $z),
         scalar(grep { $_ % $z == 0 } $x..$y),
         "[$x..$y] mod $z";
    }
  }
}

done_testing;

Вывод:

$ prove divrange.pl 
divrange.pl .. ok      
All tests successful.
Files=1, Tests=3405,  0 wallclock secs ( 0.20 usr  0.02 sys +  0.26 cusr  0.01 csys =  0.49 CPU)
Result: PASS

Ответ 6

Вот мое короткое и простое решение на С++, которое получило 100/100 на кодовости.:)
Запуск в O (1) раз. Надеюсь, его не сложно понять.

int solution(int A, int B, int K) {
    // write your code in C++11
    int cnt=0;
    if( A%K==0 or B%K==0)
        cnt++;
    if(A>=K)
        cnt+= (B - A)/K;
    else
        cnt+=B/K;

    return cnt;
}

Ответ 7

Пусть [A;B] – интервал положительных целых чисел, включающий A и B, что 0 <= A <= B, K – дивизор.

Нетрудно видеть, что в интервале [0;A] существуют N(A) = ⌊A / K⌋ = floor(A / K) факторы K:

         1K       2K       3K       4K       5K
●········x········x··●·····x········x········x···>
0                    A

Аналогично, существуют N(B) = ⌊B / K⌋ = floor(B / K) факторы K в интервале [0;B]:

         1K       2K       3K       4K       5K
●········x········x········x········x···●····x···>
0                                       B

Тогда N = N(B) - N(A) равно числу K (число целых чисел, делящихся на K) в диапазоне (A;B]. Точка A не включена, так как вычитаемая N(A) включает эту точку. Следовательно, результат должен быть увеличен на единицу, если A mod K равен нулю:

N := N(B) - N(A)

if (A mod K = 0)
  N := N + 1

Реализация в PHP

function solution($A, $B, $K) {
  if ($K < 1)
    return 0;

  $c = floor($B / $K) - floor($A / $K);

  if ($A % $K == 0)
    $c++;

  return (int)$c;
}

В PHP эффект функции floor может быть достигнут путем нажатия на целочисленный тип:

$c = (int)($B / $K) - (int)($A / $K);

который, я думаю, быстрее.

Ответ 8

(floor)(high/d) - (floor)(low/d) - (high%d==0)

Объяснение:

Существуют числа a/d, делящиеся на d от 0.0 до a. (Д!= 0)

Следовательно, (пол) (высокий/д) – (пол) (низкий/д) даст числа, делящиеся в диапазоне (низкий, высокий) (обратите внимание, что низкий исключается, и высокий уровень включен в этот диапазон)

Теперь, чтобы удалить верхний из диапазона, просто вычтите (высокий% d == 0)

Работает для целых чисел, поплавков и т.д. (используйте функцию fmodf для поплавков)

Ответ 9

Не будет стремиться к решению o (1), это уйдет для более умного человека:) Просто чувствуйте, что это идеальный сценарий использования для программирования функций. Простой и понятный.

 > x,y,z=1,1000,6
 => [1, 1000, 6] 
 > (x..y).select {|n| n%z==0}.size
 => 166 

EDIT: после чтения другого решения O (1). Мне стыдно. Программирование заставило людей лениться думать…

Ответ 10

Разделение (a/b = c) по определению – взятие набора размеров a и формирование групп размера b. Число групп такого размера, которое может быть сформировано, c, является частным от a и b. – это не более чем число целых чисел в пределах диапазона/интервала] 0..a] (не считая нуля, но включая a), которые делятся на b.

поэтому по определению:
Y/Z – число целых чисел внутри] 0..Y], которые делятся на Z
и
X/Z – число целых чисел внутри] 0..X], которые делятся на Z

следующим образом:
result = [Y/Z] – [X/Z] + x (где x = 1 тогда и только тогда, когда X делится на Y в противном случае 0 – если данный диапазон [X..Y] включает X)

пример:
для (6, 12, 2) имеем 12/2 – 6/2 + 1 (как 6% 2 == 0) = 6 – 3 + 1 = 4//{6, 8, 10, 12}
для (5, 12, 2) имеем 12/2 – 5/2 + 0 (как 5% 2!= 0) = 6 – 2 + 0 = 4//{6, 8, 10, 12}

Ответ 11

Временная сложность решения будет линейной.

Фрагмент кода:

int countDiv(int a, int b, int m)
{
    int mod = (min(a, b)%m==0);
    int cnt  = abs(floor(b/m) - floor(a/m))  +  mod;
    return cnt;
}

Ответ 12

здесь n подсчитает число и выведет сумму всех чисел, которые делятся на k

int a = sc.nextInt();
int b = sc.nextInt();
int k = sc.nextInt();
int first = 0;

if (a > k) {
  first = a + a/k;
} else {
  first = k;
}

int last = b - b%k;

if (first > last) {
  System.out.println(0);
} else {
  int n = (last - first)/k+1;
  System.out.println(n * (first + last)/2);
}

Добавить комментарий