КАФЕДРА ІНФОРМАТИКИ КАФЕДРА ІНФОРМАТИКИ
Вітаємо Вас на сайті кафедри інформатики Харківського національного педагогічного університету імені Г.С. Сковороди

Zadacha_tyzhnya_khopka_zadacha_tyzhnyaZadacha_tyzhnya_khopka_2_analiz_rezultativZadacha_tyzhnya_khopka_3_reytyngZadacha_tyzhnya_khopka_4_arhiv

 

Лічилка

 

Діти вирішили зіграти в хованки. Для того щоб вибрати, хто буде водити, вони стали в коло і почали проговорювати лічилку по складах. Той, на кого прийшовся останній склад лічилки, виходив з кола, і рахування продовжувалося з наступної дитини в колі. Врешті решт у колі залишилися одна дитина, яка й буде водити.

1. Створіть програму, яка за заданими кількістю дітей N і кількістю складів у лічилці M, знайде дитину, яка буде водити, тобто знайде значення P її порядкового номеру у колі відносно першої дитини, з якої починали рахувати.

Вхідні дані

Значення N - натуральне число не більше 10000, вводиться з клавіатури або задається як константа;
Значення M - натуральне число не більше 10000, вводиться з клавіатури;

Вихідні дані (виводяться на екран)

Значення P - натуральне число, виводиться на екран.

2. Заповніть тестову таблицю за результатами роботи програми:

 

N M P
1 1 1 1
2 2 9 2
3 10 3 4
4 41 3
5 150 11
6 300 20
7 500 21
8 550 30
9 670 15
10 930 100
11 9999 23

 

 

 

Аналіз розв'язку задачі «Лічилка»

 

Ця задача носить ім'я відомого історика першого століття Йосифа Флавія. Її формулювання пов'язано з такою легендою. Під час іудейської війни загін Йосифа, що складався з 41 особи, був оточений римлянами. Не маючи намірів здаватися у полон, воїни вирішили вишикуватися у коло та вбивати кожного третього з живих до тих пір, поки не залишиться жодної людини. Йосиф, маючи неабиякі математичні здібності, швидко розрахував, де йому потрібно стати, щоб залишитися живим.

Для вирішення задачі спочатку змінимо нумерацію дітей: зменшимо номери на 1, тобто будемо рахувати від 0. Номер дитини, яка буде водити, позначимо як PM(N), оскільки він залежить від значень M і N. Розглянемо декілька випадків.

Якщо N=1, то у нас усього одна дитина - вона і залишиться: PM(1)=0. Запам'ятаємо, що для будь-якого M значення PM(1) дорівнює нулю.

Якщо N=2, усе буде вирішувати парність числа M: якщо M - парне, то залишиться дитина з номером 0, а якщо M - непарне, то з номером 1. Тому порядковий номер дитини, що залишається у цьому випадку, PM(2)= 0 + M  mod 2. Ми записали формулу в такому вигляді (а не просто PM(2)= M mod 2), щоб підкреслити, що рахунок починається з дитини з номером 0.

Якщо N=3, то першою з кола вийде дитина з номером (M-1) mod 3. У колі залишаться дві дитини - така ж сама ситуація, як минулого разу, але тепер починаємо рахувати з наступної дитини, яка має номер M mod 3. Щоб знайти, хто ж залишиться, здійснимо "зсув" попередньої формули для N=2 на M mod 3. Отже, порядковий номер дитини, що залишиться, буде:

PM(3) = (PM(2) + M mod 3) mod 3=(PM(2) + M) mod 3

Отже, за індукцією можна вивести загальну рекурентну формулу для N>1:

PM(N)=(PM(N-1)+ M) mod N.

Кінцеве значення, одержане у такий спосіб, слід збільшити на одиницю, щоб повернутися до вихідної нумерації дітей.

Наприклад, для п'яти дітей (N=5) у колі і лічилки з 7 складів (M=7) матимемо:

P7(5)=

=(P7(4)+ 7) mod 5 =

=((P7(3)+ 7) mod 4 +7) mod 5=

=(((P7(2)+7) mod 3 +7) mod 4 +7) mod 5=

=((((P7(1)+7) mod 2 +7) mod 3 +7) mod 4 +7) mod 5

Значення останнього виразу обчислюємо, оскільки знаємо, що P7(1)=0:

P7(5)=((((0+7) mod 2 +7) mod 3 +7) mod 4 +7) mod 5=3

Отже, водитиме дитина з номером 4 (збільшуємо результат на 1).

Запишемо загальну формулу в розгорнутому вигляді:

PM(N)= (((...((0+ M) mod 2 + M) mod 3 + ... + M) mod (N-1)+ M) mod N

Як бачимо, для складання алгоритму обчислення значення P слід скористатися циклом.

Змінній-лічильнику надаватимемо значення від 2 до N.

P = 0;
для i від 2 до N
початок циклу
P = (P + M) mod i ;
кінець циклу
P = P + 1;

 

Таблиця за результатами роботи програми:

 

N M P
1 1 1 1
2 2 9 2
3 10 3 4
4 41 3 31
5 150 11 97
6 300 20 136
7 500 21 75
8 550 30 174
9 670 15 610
10 930 100 614
11 9999 23 767

 

 

Журі оцінило надіслані розв'язки наступним чином:

 

Учасник Кількість балів
1 forsh3 1
2 Юрий Дончик 4
3 SERGEY 4
4 Макс Синкевич 1
5 Kolgatin Andrey 4