Рішення головоломки Ж. АРСАКОВ h2>
Виконала учениця 11 А класу Коробова Тамара
Аркадіївна p>
Муніципальне загальноосвітній установа "Ліцей № 43» p>
Саранськ, 2004 p>
Моя
робота буде присвячена вирішенню головоломки, умова якої знаходиться в книзі
Ж. АРСАКОВ «Програмування ігор і головоломок». P>
Умова
головоломки таке: p>
Вибрали
два натуральних числа великі 1 і менші 100. Значення їх твори повідомили
пану Р, а значення суми - пану S (причому, жоден з них не знає
яке число повідомили іншому). Далі між паном Р і паном S
відбувся такий діалог: p>
Пан
Р: Я не можу знайти ці два числа. P>
Пан
S: Я знаю, що Вам це і не вдалося б. P>
Пан
Р: Ах так. Ну тоді я їх знаю. P>
Пан
S: Ну тоді і я теж їх знаю. P>
Цим
діалогом загадані числа «обчислюються» однозначно. p>
Я
склала програму на мові Pascal, яка «аналізує» висловлювання
пана Р і пана S і тому, природно, складається з 4 частин: p>
1)
перша «відкидає» пари, що складаються з простих чисел; p>
2)
другий «відкидає» з решти пар такі, сума яких може бути
представлена у вигляді двох простих доданків; p>
3)
третя - ті пари чисел, твір яких зустрічається у який-небудь інший
пари чисел, яка, до речі, теж буде відкинута; p>
4)
четверта - ті пари чисел, сума яких зустрічається у якої-небудь іншої пари
чисел, яка, до речі, теж буде відкинута. p>
Тепер
про саму програму: для зберігання інформації про пари чисел я використовую двовимірний
булевський масив b, в який на відповідні місця я буду записувати
«Істину», якщо пара чисел задовольняє умові задачі на даному кроці і,
природно, «брехня», якщо - ні. До речі, щоб числа i, j і j, i не вважалися
двічі перебір йде тільки по половині таблиці. p>
Булевського
процедура prost буде «істиною», якщо число х - просте і «брехнею», якщо --
складене. p>
Решта
пояснення знаходяться в ремарка самої програми. p>
const n = 99; p>
m = (n-1) * n div 2; p>
var b: array [2 .. 250,2 .. 250] of
boolean; p>
i, j, k, l, p, vs1, vs2, vs3, vs4, sum, s:
word; p>
fin: boolean; p>
function prost (x: word): boolean; (істина, якщо х - просте число) p>
var da: boolean; p>
p: word; p>
begin p>
da: = true; p>
if x> 2 then p>
for p: = 2 to trunc (sqrt (x)) do if
x = (x div p) * p then da: = false; p>
prost: = da; p>
end; p>
begin p>
(починається
перший крок - будуть відкинуті ті пари чисел, p>
у
яких обидва числа - прості) p>
writeln ( 'при n =', n); p>
vs1: = 0;
(vs1 - кількість рішень після першого кроку) p>
for i: = 2 to n do p>
for j: = i to n do p>
begin p>
if prost (i) and prost (j) then
b [i, j]: = false p>
else begin b [i, j]: = true; vs1: = vs1 1;
end; p>
end; p>
writeln ( 'vs1 =', vs1: 5, 'iz', m); p>
s: = 0;
(s-кількість рішень, які будуть відкидатися надалі) p>
(починається
другий крок - будуть відкинуті ті пари чисел i, j, сума яких p>
може
бути представлена у вигляді двох простих доданків) p>
for i: = 2 to n do p>
for j: = i to n do p>
begin p>
if b [i, j] then p>
begin p>
sum: = i + j; fin: = false; k: = 2; p>
while (not fin) and (k <= (sum div
2)) do p>
begin p>
if prost (k) and prost (sum-k) then
fin: = true; p>
k: = k +1; p>
end; p>
if fin then begin b [i, j]: = false;
s: = s +1; end; p>
end; p>
end; p>
vs2: = vs1-s; writeln ( 'vs2 =', vs2: 5, '
iz ', m); p>
(починається
третій крок - будуть відкинуті ті пари чисел i, j, твір p>
яких
зустрічається у якої-небудь іншої пари чисел, яка, до речі, p>
теж буде відкинута) p>
for i: = 2 to n do p>
for j: = i to n do if b [i, j] and
(i = 98) and (j = 99) then writeln (i: 3, j: 3); p>
for i: = 2 to n do p>
for j: = i to n do p>
begin p>
if b [i, j] then p>
begin p>
p: = i * j; fin: = false; k: = 2; p>
while k <= n do p>
begin p>
l: = k; p>
while l <= n do p>
begin p>
if b [k, l] and (p = k * l) and
(i <> k) then p>
begin fin: = true; b [k, l]: = false;
s: = s +1; end; p>
l: = l +1; p>
end; p>
k: = k +1; p>
end; p>
if fin then begin b [i, j]: = false;
s: = s +1; end; p>
end; p>
end; p>
vs3: = vs1-s; writeln ( 'vs3 =', vs3: 5, '
iz ', m); p>
(починається
четвертий крок - будуть відкинуті ті пари чисел i, j, сума p>
яких
зустрічається у якої-небудь іншої пари чисел, яка, до речі, p>
теж буде відкинута) p>
for i: = 2 to n do p>
for j: = i to n do p>
begin p>
if b [i, j] then p>
begin p>
sum: = i + j; fin: = false; k: = 2; p>
while k <= n do p>
begin p>
l: = k; p>
while l <= n do p>
begin p>
if b [k, l] and (sum = k + l) and
(i <> k) then p>
begin fin: = true; b [k, l]: = false;
s: = s +1; end; p>
l: = l +1; p>
end; p>
k: = k +1; p>
end; p>
if fin then begin b [i, j]: = false;
s: = s +1; end; p>
end; p>
end; p>
vs4: = vs1-s; writeln ( 'vs4 =', vs4: 5, '
iz ', m); p>
for i: = 2 to n do p>
for j: = i to n do if b [i, j] then
writeln (i: 4, j: 4); p>
readln p>
end. p>
Тепер
про результати: p>
1)
виявляється при тих умовах, які повідомлені у книзі (числа більше 1 і менше
100, тобто від 2 до 99 включно, тому спочатку у програмі константа
n = 99) завдання має два рішення: p>
(4; 13)
і (98; 99); p>
2)
але якщо умови змінити: числа від 2 до 100 включно, то друге рішення
(98; 99) відкидається на 4 кроці, тому що є дві пари чисел з такою сумою:
(98; 99) і (97; 100). P>
Всі
це спонукало мене досліджувати цю задачу більш детально: за яких ще
значеннях n це завдання буде мати єдине рішення. p>
Досить
видозмінити наведену програму (n тепер буде не константою, а змінної
і взяти всю програму всередину циклу з цієї змінної від 5 до 110). p>
Результати
виявилися такі: p>
При
достатньо малих значеннях n (n <35) завдання або не мала рішення (при n = 5,
7, 8, 10, 11, 13, 16, 17, 20, 22, 23, 25, 28, 31, 32), або мала тільки одне
рішення рівне числах (n-1) і n (при n = 6, 9, 12, 14, 15, 18, 19, 21, 24, 26,
27, 29, 30, 33, 34). P>
При
n = 35 стався якісний стрибок: тепер рішення були завжди, причому при
деяких значеннях n (при n = 35, 37, 38, 41, 43, 46, 50, 52, 53, 55, 56, 58,
65, 67, 70, 71, 76, 77, 80, 83, 85, 88, 91, 92, 97, 98, 100, 101, 107) це було
єдине рішення однакове для всіх n: (4; 13), а при інших значеннях
n> 35 додавалося ще одне рішення: (n-1; n). p>
Список літератури h2>
Ж. Арсак,
«Програмування ігор і головоломок», М., Наука, 1990р. P>
Для
підготовки даної роботи були використані матеріали з сайту http://licey43.ru
p>