asyan.org
добавить свой файл
1

Школа олімпійського резерву, ВІППО

Заняття 2

Тема: Поняття довгого числа. Використання числових і символьних масивів для подання довгого числа. Зчитування довгого числа з файлу.
Відомо, що арифметичні дії, виконувані комп'ютером в обмеженому числі розрядів, не завжди дозволяють отримати точний результат. Більш того, ми обмежені розміром (величиною) чисел, з якими можемо працювати. А якщо нам необхідно виконати арифметичні дії над дуже великими числами, наприклад

30! == 265252859812191058636308480000000?

В таких випадках ми самі повинні поклопотатися про представлення чисел в машині і про точне виконання арифметичних операцій над ними.

Числа, для представлення яких в стандартних комп'ютерних типах даних не вистачає кількості двійкових розрядів, називаються "довгими". Реалізація арифметичних операцій над такими "довгими числами" отримала назву "довгої арифметики".

Організація роботи з "довгими числами" багато в чому залежить від того, як ми розмістимо в комп'ютері ці числа. "Довге число" можна записати, наприклад, за допомогою масиву десяткових цифр, кількість елементів в такому масиві рівно кількості значущих цифр в "довгому числі". Але якщо ми реалізовуватимемо арифметичні операції над цим числом, то розмір масиву повинний бути достатнім, щоб розмістити в ньому і результат, наприклад, множення.
Проаналізуємо...

Число з якою максимальною кількістю цифр можна записати у змінну типу INTEGER?

Чотири (9999), тому що INTEGER лежить в межах від -32758 ... 32767.
А в LONGINT?

Дев’ять (999 999 999), тому що LONGINT лежить в межах

-2 147 483 648 ... 2 147 483 647.

Якщо кількість цифр більша ( наприклад число 265252859812191058636308480000000), то число можна зчитати посимвольно в масив (CHAR, але для виконання операцій краще INTEGER).


I

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

A[I]

2

6

5

2

5

2

8

5

9

8

1

2

1

9

1

0

5

8

6

3

0

8

4

8

0

0

0

0

0

0


Таке представлення буде проблематичним при виконанні операцій, які при роботі з „довгими” числами виконуються в стовпчик з кінця, тобто числа різної довжини треба зрівнювати, добавляючи на початок нулі.
Тому краще зчитати зразу ж число в зворотному порядку, записавши в A[0] кількість цифр.

Програмний код реалізації зчитування в масив по одній цифрі в зворотному порядку:
program raad_long;

var a:array[0..1000] of integer;

i:integer;

f:text;

c:char;

begin

assign(f,'input.dat');

reset(f);

for i:=0 to 1000 do a[i]:=0;
while not(eoln(f)) do begin

read(f,c);

if c in ['0'..'9'] then begin

for i:=a[0] downto 1 do a[i+1]:=a[i];

a[0]:=a[0]+1;

a[1]:=ord(c)-ord('0');

end;

end;

end.

Існують і інші представлення "довгих чисел". Розглянемо одне з їх.

Уявно наше число

30! = 265252859812191058636308480000000

у вигляді:

Номер елемента в масиві А

0

1

2

3

4

5

6

7

8

9

Значення

9

0

8000

3084

8636

9105

8121

2859

6525

2

Ми можемо вважати, що наше "довге число" представлено в 10000 системі числення (десятково-десяткова система числення), а "цифрами" числа є чотиризначні числа.

Виникають питання. Що за 9 в А [ 0 ], чому число зберігається задом наперед ? Відповіді очевидні, але почекаємо з передчасними поясненнями. Відповіді на питання будуть ясні з тексту.

^ Ввести "довге число" з файлу. Рішення задачі почнемо з опису даних.

Const MaxDig=1000;
{Максимальна кількість цифр — чотиризначних!}

  Osn=10000; {Основа нашої системи числення, в елементах масиву бережемо чотиризначні числа} 
Type Tlong=Array[0..MaxDig] of Integer;

{Максимальна кількість десяткових цифр в нашому числі?}

Алгоритм введення "довгого числа" з файлу розглянемо на конкретному прикладі.

Нехай у файлі записано число 238516745 і основою (Osn) є 10000 (збережемо по чотири цифри в елементі масиву А). Зміна значень елементів масиву А в процесі введення (посимвольно в змінну ch) відображено в таблиці:


А[0]

А[1]

А[2]

А[3]

ch

Примітка

3

6745

3851

2

-

Кінцевий стан

0

0

0

0

2

Початковій стан

1

2

0

0

3

1-й крок

1

23

0

0

8

2-й крок

1

238

0

0

5

3-й крок

1

2385

0

0

1

4-й крок

2

3851

2

0

6

5-й крок: старша цифра елемента А [1] перейшла в поки "порожній елемент" А[2]

2

8516

23

0

7

5-й крок

2

5167

238

0

4

6-й крок

3

1674

2385







7-й крок

3

6745

3851

2

 

 




Проаналізуємо таблицю  (і отримаємо відповіді на поставлені вище питання).
1. В А [ 0 ] зберігаємо кількість задіяних (ненульових) елементів масиву А — це вже очевидно.

2. При обробці кожної чергової цифри вхідного числа старша цифра елемента масиву з номером i стає молодшою цифрою числа в елементі i + 1, а цифра, що вводитися, буде молодшою цифрою числа з А [ 1 ] . В результаті роботи нашого алгоритму мі отримали число, записане задом наперед.

Наприклад, виписати фрагмент тексту процедури перенесення старшої цифри з А[i]B молодшу цифру А [ i +1 ], тобто зсув вже введеної частини числа на одну позицію управо:

For i:=A[0] DownTo 1 Do Begin
          А[i+l]:=A[i+l]+(Longint(А[i])*10) Div Osn;
          А[i]:=(LongInt(А[i])*10) Mod Osn;
End;


^ Завдання на самостійне опрацювання


  1. Написати програмний код зчитування в масив „довгого” числа з файлу по 4 цифри (основа 10000) в зворотному порядку.

  2. Подумати, яким чином можна б було реалізувати виведення „довгого” числа.

  3. Проаналізувати і розібратися з задачею

(І тур Волинська Інтернет-олімпіада 2004 рік)

Умова


І ось настав день...

Вхідний файл: input.txt
Вихідний файл: output.txt
І ось настав день, ракета була готова. Всі жителі Квіткового міста зібралися на головній площі. Незнайко відправлявся до зірок! Він допоміг Знайку знайти координати планети Незнайкафілтера, і в нагороду його відправили до подорожі першим. Помічником Незнайка узяв Пампушку. В кораблі не було більше місця, адже Незнайкафілтера знаходиться далі ніж Місяць, і тому треба було брати набагато більше палива. Момент настав. Ракета відірвалася від Землі і спрямувалася до зірок!

Йшов другий місяць польоту, ракета наблизилася до наміченої цілі. Ось вона - невідома планета. Ракета приземлилася, і її оточили місцеві жителі. Космонавтів обдарували подарунками. "В чому справа?" - поцікавився Незнайко. "Ви пролетіли цілу кількість космометров, і це свято "Цілого Космоса""- відповіли йому. Незнайко довго розпитував місцевих жителів про все. І він взнав, що поряд знаходиться ще одна планета цього народу, Незнайкафобтерра, але на ній живе клан, який в свято "Цілого Космосу" вбиває всіх хто до них прилетить. А один космометр рівний 3-м кілометрам. Незнайкові повідомили відстань від центру галактики до Незнайкафілтери і Незнайкафобтери. Причому Незнайко вилітає в день Великого протистояння, коли обидві планети і центр галактики знаходяться на одній прямій. Скажіть, чи варто летіти Незнайкові і скільки кілометрів йому доведеться пролетіти.
Вхідні дані: В першому і другому рядках файлу записані числа, що містять не більше 300 знаків - відстані до Незнайкафілтери і Незнайкафобтери (в кілометрах).

Вихідні дані: Вихідний файл повинен містити в першому рядку слово "Yes", якщо обчислення були проведені правильно і "No", якщо ні (слова треба виводити без лапок), а в другій відстань, яка доведеться пролетіти Незнайку (теж в кілометрах).

Приклад:
input.txt

22222222222222222222
33333333333333333333

output.txt
Yes
11111111111111111111