На необитаемый остров попало 5 человек и одна обезьяна . Весь день собирали они кокосовые орехи: собрали хорошую кучу! Ночью один из друзей решил забрать свою долю - разделил он орехи на 5 равных частей, при этом остался один лишний кокос - его он отдал обезьяне, забрал свою часть кокосов и лег спать. Точно так же поступили и оставшиеся четверо - каждый вставал делил орехи на 5 равных частей , у каждого оставался один орех, который доставался обезьяне. Свою долю деливший забирал и ложился спать. На утро друзья еще раз разделили остаток орехов на 5 равных частей, а вот обезьяне на утро ореха не досталось. Сколько всего было орехов? Гарднер не даёт решения, лишь отмечая, что найти решение непросто. На компьютера подобные задачи решаются в доли секунды, даже если использовать обычный перебор. Однако, попытка решить задачу "кавалерийским наскоком" с помощью "Поиска решения" электронных таблиц EXCEL не увенчалась успехом. Не известно, что за алгоритм используется для целочисленного решения. Используя традиционное программирование (написав макрос на VBA) решение было получено моментально, так как алгоритм решения элементарен. Схема алгоритма приведена на следующей странице. Далее следует текст макроса. Он приведен для того, чтобы пояснить маленькую хитрость, примененную в решении. Естественно, что в любом случае число орехов должно быть целым, однако для того чтобы компьютер "почувствовал" наличие остатка при делении на пять число орехов ( переменные KOKOS) объявлены как действительные числа. Для "обнаружения" остатка использованы функции VBA INT и FIX. Текст макроса VBA Private Sub Command1_Click() Dim KOKOS As Double, KI As Integer Dim KOKOS1 As Double, KF As Integer Dim KOKOS2 As Double, KOKOS3 As Double, KOKOS4 As Double, KOKOS5 As Double Rem ПРОИЗВОЛЬНОЕ НАЧАЛЬНОЕ ЧИСЛО СОБРАННЫХ КОКОСОВ KOKOS = 10# Rem ОПЕРАТОР С МЕТКОЙ 5 БУДЕТ УВЕЛИЧИВАТЬ ЧИСЛО КОКОСОВ СОГЛАСНО УСЛОВИЯМ 5 KOKOS = KOKOS + 1# Rem ================================ Rem ДЕЛИТ ПЕРВЫЙ УЧАСТНИК Rem================================== KI = Int(-(KOKOS - 1) / 5) 'полученое с дробным остатком число округляется до меньшего целого================================================================ KF = Fix(-(KOKOS - 1) / 5) 'полученое с дробным остатком число округляется до большего целого================================================================ If Abs(KI) - Abs(KF) <> 0 Then GoTo 5 ' если деление на 5 имеет остаток уходим на увеличение числа !====================================================== If Abs(KI) - Abs(KF) = 0 Then KOKOS1 = KOKOS - (KOKOS - 1) / 5 - 1 ' осталось после первого ZABRAL1 = (KOKOS - 1) / 5 Rem следующие четыре блока аналогичны первому=========================== KI = Int(-(KOKOS1 - 1) / 5) KF = Fix(-(KOKOS1 - 1) / 5) If Abs(KI) - Abs(KF) <> 0 Then GoTo 5 If Abs(KI) - Abs(KF) = 0 Then KOKOS2 = KOKOS1 - (KOKOS1 - 1) / 5 - 1 ZABRAL2 = (KOKOS1 - 1) / 5 Rem ДЕЛИТ ТРЕТИЙ УЧАСТНИК========================================= KI = Int(-(KOKOS2 - 1) / 5) KF = Fix(-(KOKOS2 - 1) / 5) If Abs(KI) - Abs(KF) <> 0 Then GoTo 5 If Abs(KI) - Abs(KF) = 0 Then KOKOS3 = KOKOS2 - (KOKOS2 - 1) / 5 - 1 ZABRAL3 = (KOKOS2 - 1) / 5 Rem ДЕЛИТ ЧЕТВЕРТЫЙ УЧАСТНИК=================================== KI = Int(-(KOKOS3 - 1) / 5) KF = Fix(-(KOKOS3 - 1) / 5) If Abs(KI) - Abs(KF) <> 0 Then GoTo 5 If Abs(KI) - Abs(KF) = 0 Then KOKOS4 = KOKOS3 - (KOKOS3 - 1) / 5 - 1 ZABRAL4 = (KOKOS3 - 1) / 5 Rem ДЕЛИТ ПЯТЫЙ УЧАСТНИК======================================== KI = Int(-(KOKOS4 - 1) / 5) KF = Fix(-(KOKOS4 - 1) / 5) If Abs(KI) - Abs(KF) <> 0 Then GoTo 5 If Abs(KI) - Abs(KF) = 0 Then KOKOS5 = KOKOS4 - (KOKOS4 - 1) / 5 - 1 ZABRAL5 = (KOKOS4 - 1) / 5 Rem ВЫВОД РЕЗУЛЬТАТОВ НА ЭКРАН В РАБОЧИЙ ЛИСТ EXCEL ============ Range("D6").Value = KOKOS Range("D7").Value = ZABRAL1 Range("D8").Value = ZABRAL2 Range("D9").Value = ZABRAL3 Range("D10").Value = ZABRAL4 Range("D11").Value = ZABRAL5 Rem ПОСЛЕДНИЙ УТРЕННИЙ ДЕЛЕЖ NA_UTRO = (KOKOS - ZABRAL1 - ZABRAL2 - ZABRAL3 - ZABRAL4 - ZABRAL5 - 5) / 5 Rem Print " А ПО УТРУ КАЖДЫЙ ПОЛУЧИЛ ЕЩЁ" Range("D13").Value = NA_UTRO End Sub Tрадиционное программирование требует некоторых затрат времени на написание и отладку макроса( естественно, если Вы владеете VBA). С помощью написанного макроса задача была решена моментально.
|