Кафедра інформатики

Харківський національний педагогічний університет імені Г.С. Сковороди

Кафедра інформатики

Харківський національний педагогічний університет імені Г.С. Сковороди

Задача тижня 2011

Задача тижня 30.01.12 – 05.02.12

Zadacha_tyzhnya_khopka_zadacha_tyzhnyaZadacha_tyzhnya_khopka_2_analiz_rezultativZadacha_tyzhnya_khopka_3_reytyngZadacha_tyzhnya_khopka_4_arhiv

 

Масовий забіг

 

Учасникам масового забігу перед стартом були видані нагрудні знаки з номерами, що відповідають порядку їх реєстрації. Після забігу вони склали ці знаки в ряд один за одним у порядку свого прибуття на фініш, утворивши таким чином N-розрядне число.

1. Створіть програму, яка за заданим N обчислює кількість учасників забігу k. Реалізуйте перевірку правильності заданого значення N:

Вхідні дані

Значення N (кількість розрядів числа) – натуральне число не більше за 2147483647, вводиться з клавіатури.

Вихідні дані

Значення k (кількість учасників забігу) – натуральне число, виводиться на екран.

Якщо значення N є помилковим, вивести значення k, яке дорівнює -1.

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

 

N k
199
210-1
31110
41
5189
62893
730001
8788888889
92147483644
102147483647

 

Аналіз розв’язку задачі «Масовий забіг»

 

Розглянемо спочатку алгоритм, який надіслав Юрій Дончик.

Якщо число, яке склали учасники забігу, не перевищує 9, то усі номери однорозрядні, і кількість учасників дорівнює N. Подальше збільшення кількості учасників означає перехід до дворозрядних номерів, останній з яких – 99. Нескладно обчислити, що номери 99-ти учасників складуть число довжиною в N=189 цифр. Аналогічні міркування можна продовжувати для тризначних, чотиризначних і т.д. номерів.

Алгоритм Юрія Дончика:
якщо N≤9 то k=N інакше
якщо (N≤189) and (N mod 2 =1) то k=9+(N-9) div 2 інакше
якщо (N≤2889) and ((N-189) mod 3=0) то k=99+(N-189) div 3 інакше
якщо (N≤38889) and ((N-2889) mod 4=0) то k=999+(N-2889) div 4 інакше
якщо (N≤488889) and ((N-38889) mod 5=0) то k=9999+(N-38889) div 5 інакше
якщо (N≤5888889) and ((N-488889) mod 6=0) то k=99999+(N-488889) div 6 інакше
якщо (N≤68888889) and ((N-5888889) mod 7=0) то k=999999+(N-5888889) div 7 інакше
якщо (N≤788888889) and ((N-68888889) mod 8=0) то k=9999999+(N-68888889) div 8 інакше
якщо (N≤8888888889) and ((N-788888889) mod 9=0) то k=99999999+(N-788888889) div 9 інакше k=-1;
Цей алгоритм є ефективним за часом обчислення, оскільки певну розрахункову роботу було виконано «ручним» способом на етапі розробки алгоритму.

 

Узагальнимо наведений алгоритм, забезпечивши обчислення констант у циклі. Спосіб обчислення рубіжних констант стає більш прозорим, якщо послідовно віднімати з N кількість цифр, яку утворюють однорозрядні, дворозрядні, трирозрядні і т.д. номери.

k=0
якщо N>9 то k=k+9; N=N-9;
якщо N>90*2 то k=k+90; N=N-90*2;
якщо N>900*3 то k=k+900; N=N-900*3;
якщо N>9000*4 то k=k+9000; N=N-9000*4;
якщо N>90000*5 то k=k+90000; N=N-90000*5;
якщо N>900000*6 то k=k+900000; N=N-900000*6;

…………………………………………………

Нарешті будуємо цикл:
p = 9;
i = 1;
k = 0;
поки N div i > p
початок циклу
k = k + p;
N = N – p * i ;
i = i + 1;
p = p * 10;
кінець циклу;
k = k + N div i;
якщо N mod i ≠ 0 то k = -1;

 

Розглянутий підхід було застосовано в розв’язках авторів під псевдонімами forsh3 і RomaN. Але звернемо увагу на суттєвий момент: формулюючи умову циклу, слід запобігти виходу значення арифметичного виразу за межі чотирибайтного цілого. Саме це ми і передбачили, записавши умову у вигляді N div i > p.

Іншим способом розв’язку задачі є послідовне віднімання від заданого N кількості цифр у номерах учасників забігу, починаючи з першого, доки різниця не стане нульовою, і тоді кількість учасників знайдено, або від’ємною, і тоді слід вивести значення -1. Але такий підхід потребує виконання комп’ютером значно більшої кількості операцій.

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

 

N
k
199
210
-1
311
10
411
518999
628931000
7300017777
878888888999999999
92147483644-1
102147483647-1

 

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

 

Учасник Кількість балів
1RomaN4
2Макс Синкевич2
3Kolgatin Andrey4
4Юрий Дончик4
5SERGEY2
6forsh33