Программирование игр и головоломок - [66]

Шрифт
Интервал

, b, p через а', b', p' соответственно:

а' = 2*а, p' = p/2 − а/2 − b, b' = a + b.

Для этих значений получаем:

a'*p' = a*pa>2 − 2a*b = а*р − (а + b)>2 + b>2 = а*рb'>2 + b>2.

Это, наконец, дает

а'*p' + b'>2 = а*р + b>2.

Инвариантной величиной цикла оказывается, таким образом, сумма ар + b>2, причем p остается четным. Это обеспечивается тем, что в случаях, когда p/2 нечетно, мы вычитаем нечетные b из нечетного p/2. Что касается b, то он нечетен потому, что он начинается со значения 1 и к нему прибавляются только четные значения а.

В начале а = 4, p (целая часть дроби (n − 1)/4) четно, b = 1, так что ар + b>2 = n.

Наконец, a, начиная с 4, умножается на 2 при каждом прохождении цикла; b начинается с 1, которое меньше соответствующего начального а = 4.

Тогда при переходе от a, b, p к a', b', p' либо

b' = b, а' = 2*а, так что если b < а, то и b' < а';

либо

b' = а + b, а' = 2*а, что также сохраняет справедливость отношения а' < b'.

Следовательно, вот ситуация, которую цикл оставляет инвариантной:

n = а*p + b>2;

а — степень двойки,

p четно,

b нечетно, b < а.

Кроме того, мы знаем, что при выходе из цикла p < а.

Если p равно нулю, то n = b>2. Тогда мы видим, что n — квадрат числа b, которое выводится, и все закончено.

Но n может оказаться полным квадратом и тогда, когда p не нуль. Попробуем рассмотреть все возможные случаи. Положим n = r>2 (r нечетно). Соотношение

r>2 = ар + b дает

r>2b>2 = ар.

Положим r + b = 2u, rb = 2v (r и b нечетны). Отсюда получаем 4uv = ар.

Поскольку r = u + v, где r нечетно, получаем, что u и v не могут быть числами одинаковой четности, так что одно из них четно, а другое нечетно. Так как а является степенью двойки, то нечетный сомножитель относится к p. Выявим его, полагая р = s2>t, где s нечетно, a t ≥ 1 (p четно).

Напомним, что а = 2>k. В этих обозначениях 4uv = ар = s2>k+t, uv = s2>k+t−2.

Возможные решения для пары u, v имеют вид пар

s'2>k+t-2, s''

где s's" = s.

Покажем сначала, что s" — меньший из этих двух элементов пары. Вследствие t ≥ 1 имеем ktk + t − 2.

Вследствие p < а последовательно выводим

s2>t < 2>k,

s's"2>t < 2>k.

s's" < 2>k-t ≤ 2>k+t-2s'>22>k+t-2

(потому что s' нечетен и не меньше 1).

Следовательно, нужно взять u = s'2>k+t-2, v = s".

Покажем теперь, что нужно обязательно взять s' =1, s" = s. По выбору u и v

b = 2>k+t−2s' − s" < а = 2>k.

Отсюда получаем:

s" > 2>k+t−2s' − 2>k,

и, так как t ≥ 1:

s" > 2>k−1s' − 2>k,

s = s's" > 2>k−1s'>2 − 2>ks = 2>k−1s' (s' − 2).

Вследствие р = s2>t < а = 2>k выводим s < 2>kt ≤ 2>k−1.

Объединим два полученных неравенства:

2>k−1s' (s' − 2) < x < 2>k−1, поэтому s' (s' − 2) < 1.

Единственное нечетное число s', удовлетворяющее этому соотношению, это s' = 1. Следовательно, у нас остается единственная возможность:

u = 2>k+t-2, v = s,

b = uv = 2>k+t-2s < а = 2>k,

s > 2>k+t-2 − 2>k.

Так как s < 2>kt, то t должно быть таким, чтобы

2>kt > 2>k+t-2 − 2>k.

Поскольку t должно быть строго положительно, то его единственными возможными значениями являются t = 1 и t = 2.

При t = 1 имеем

p = 2s, b = 2>kts = a/2 − p/2.

Следовательно, если 2b = аp, то n — квадрат числа (а + p)/2 = аb.

При t = 2 имеем

p = 4s, b = 2>ks = ap/4.

Следовательно, если p = 4(ab), то n — квадрат числа a + p/4 = 2аb.

Этим исчерпываются случаи, когда n может быть полным квадратом.

Можно спросить себя, могут ли эти различные случаи действительно осуществляться. Заметим, что при вступлении в цикл у нас b = 1, a = 4. После этого b может быть изменено добавлением а, т. е. кратным числа 4. Следовательно, b остается сравнимым с 1 по модулю 4. В трех возможных случаях:

p = 0, r = b,

p = а − 2b, r = ab,

p = 4 (ab), r = 2ab,

первый случай — единственный, в котором квадратный корень из n сравним с 1 по модулю 4; два других дают квадратный корень, сравнимый с 3 по модулю 4. При выходе из цикла равенство

b = ар + b>2

с учетом соотношений p < a, b < a дает n < 2a>2 и, следовательно, при выходе из цикла a>2 > n/2. Равенство

ар = nb>2

дает p = (nb>2)/a < n/а.

Если окажется, что n/а < a, то непременно p < а и цикл закончен. Чтобы цикл остановился, необходимо, чтобы a>2 > n/2, и цикл заведомо останавливается, если a>3 > n.

Следовательно, все зависит от положения n по отношению к степеням двойки. Существует такое целое n, что

4>q < n < 4>q+1.

Возможны два случая. Во-первых, может выполняться неравенство

4>q = 2>2q < n < 2>2q+1,

и тогда для k = q число a>2 = 2>2q > n/2 может быть значением остановки, но в этом нет уверенности. С другой стороны, если

2>2q+1 < n < 2>2q+2,

то единственное значение a, удовлетворяющее условию a>2 > n/2, есть a = 2>q+1, и для этого значения имеем a>2 > n, что гарантирует остановку. Поскольку r = ab, то а = r + b > r и, следовательно, a>2 > n.

Во втором случае

r = 2ab и b < а, откуда а < 2ab = r.

Таким образом, все три распознаваемые программой случая являются единственными возможными исходами программы, и каждый из них может произойти.

Таким образом, перед нами — очень забавный алгоритм, который дает значение квадратного корня, и который определяет случай, когда n не является корнем, но в этом случае не дает никакой дополнительной информации.

Программа заведомо останавливается при


Рекомендуем почитать
Обратные вызовы в C++

В практике разработки ПО зачастую встает задача динамической модификации программного кода в зависимости от текущих или настраиваемых значений параметров. Для решения этой задачи широко используются обратные вызовы. В языке C++ обратные вызовы реализуются различными способами, и далеко не всегда очевидно, какой из них лучший для конкретной ситуации. В книге рассмотрены теоретические и практические аспекты организации обратных вызовов, проанализированы достоинства и недостатки различных реализаций, выработаны рекомендации по выбору в зависимости от требований к проектируемому ПО.


Теоретический минимум по Computer Science

Хватит тратить время на скучные академические фолианты! Изучение Computer Science может быть веселым и увлекательным занятием. Владстон Феррейра Фило знакомит нас с вычислительным мышлением, позволяющим решать любые сложные задачи. Научиться писать код просто — пара недель на курсах, и вы «программист», но чтобы стать профи, который будет востребован всегда и везде, нужны фундаментальные знания. Здесь вы найдете только самую важную информацию, которая необходима каждому разработчику и программисту каждый день. «Эта книга пригодится и для решения повседневных задач.


Язык PL/SQL

В учебно-методическом пособии рассматриваются основы языка программирования PL/SQL, реализованного в системе управления базами данных Oracle Database Server. Приводятся сведения о поддерживаемых типах данных, структуре программ PL/SQL и выполнении SQL-предложений в них. Отдельно рассмотрено создание хранимых в базах данных Oracle программ PL/SQL – процедур, функций, пакетов и триггеров.


Перевод в электронный формат, кодированные наборы шрифтов и система Оптического Распознавания Символов для многошрифтовых информационных ресурсов на примере “Летописи журнальных статей”

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Программирование на языке Пролог для искусственного интеллекта

Книга известного специалиста по программированию (Югославия), содержащая основы языка Пролог и его приложения для решения задач искусственного интеллекта. Изложение отличается методическими достоинствами — книга написана в хорошем стиле, живым языком. Книга дополняет имеющуюся на русском языке литературу по языку Пролог.Для программистов разной квалификации, специалистов по искусственному интеллекту, для всех изучающих программирование.


Программирование на Visual C++. Архив рассылки

РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.