Читаем Программирование игр и головоломок полностью

— есть 15 способов взять две шашки среди 6 и, самое большее, 4 способа соединить их между собой, следовательно, самое большое 60 комбинаций с двумя шашками. Но их уже гораздо больше для трех шашек. Испытать все комбинации за разумное время не представляется возможным.

Когда вы излагаете решение, вы берете две шашки из 6, соединяете их между собой одной из четырех операций (на самом деле можно считать, что только тремя, начинать с деления — это исключение). Есть 60 (или, скорее, 45) способов это сделать. После этого задача сводится к задаче с 5 шашками. При таком подходе решение кажется более достижимым.

Следовательно, попробуем. Самые большие упрощения возникают, если вы не ищете для данного числа приближенных значений. Компьютер выводит результат, если он его находит; в противном случае он сообщает, что он решения не нашел. Вы сами можете систематически проводить одну попытку за другой. Пусть pi, pj, pk обозначают три из 6 шашек. Вы можете искать решение в виде

pi * комбинация из 5 оставшихся шашек = n,

pj + pi * комбинация из 4 оставшихся шашек = n,

pj + pi * комбинация из 4 оставшихся шашек = n,

±(pjpk) + pi * комбинация из 3 оставшихся шашек = n,

где ◦ означает одну из четырех разрешенных операций. Удивительным образом все это очень быстро и очень часто приводит к точному ответу. Никто на запрещает вам попробовать что-то лучшее…

В соответствии с заглавием примера попытайтесь поэтому для 6 шашек 10, 10, 25, 50, 75, 100 найти 370, 369, 368…

7. Обо всем понемногу

В этом разделе я объединил различные задачи, среди которых далеко не все являются головоломками, по той причине, что опыт показывает: средний программист в них достигает цели не бее труда. Для некоторых из них в различных книгах можно найти многочисленные решения, не всегда правильные, или — во всяком случае — не всегда хорошие, или слишком плохо объясненные. Условия этих задач могут показаться мало привлекательными. Но если в программировании вы любите именно трудности, не поддавайтесь первому впечатлению.

* Головоломка 29. Дихотомический поиск.

Это — совершенно известная задача. Вам предлагается упорядоченная таблица попарно различных элементов; например, в порядке возрастания. Вам предлагается, кроме того, другой элемент: его нужно разместить в таблицу.

Следовало бы уточнить (хоть это и не в моих правилах: обычно я предоставляю вам заботу об уточнении. В этой книге вовсе не я тот человек, который должен аккуратно работать…). Пусть a — таблица с n элементами, упорядоченная так, что

a[i] < a[i + 1] для 1 < in,

и x — элемент, который нужно разместить. Его место

0, если xa[1],

i, если a[i] < xa[i + 1],

n, если a[n] < x.

Один сотрудник факультета Нотр-Дам де ла Пэ в Намюре изучил 18 программ, опубликованных различными авторами по всему свету и в каждой нашел хоть что-то, за что можно упрекнуть. Всякий раз, когда я получаю новую книгу по программированию (к счастью, я получаю не все), я смотрю, нет ли там случайно исследования этой задачи. Почти во всех случаях это так. Настоящий «ослиный мост»[16] информатики…

* Головоломка 30. Равенство «с точностью до пробелов».

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

Если вы находите это совершенно элементарным, вы можете изучить, являются ли данные цепочки обращениями друг друга с точностью до пробелов. Вы можете также увидеть, является ли цепочка палиндромом (т. е. совпадает со своим обращением) с точностью до пробелов, Так, палиндромами являются

А РОЗА УПАЛА НА ЛАПУ АЗОРА

АРГЕНТИНА МАНИТ НЕГРА

Попытайтесь получить правильную (это уж как минимум) и элегантную программу.

Головоломка 31. Анаграмма.

Еще одна головоломка, вопреки ее внешнему виду, Дело в том, чтобы сказать, являются ли две цепочки букв анаграммами друг друга (т. е. получаются ли они друг из друга перестановками букв). Эта задача имеет совершенно различный вид в зависимости от того, разрешите ли вы себе изменять обе цепочки или порождать новые цепочки, или нет. Выбор я предоставляю вам… Может быть, вы заметите, что различные решения следует оценивать в зависимости от соотношения между размерами цепочек и используемого алфавита. Подумайте о крайних случаях: алфавит из 26 букв и цепочка из 1000 символов; алфавит из 1000 символов (это вроде китайского…) и цепочка из 10 символов.

Головоломка 32. Анаграмма с точностью до пробелов.

Перейти на страницу:

Похожие книги

Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных
Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ
Эффективное использование C++. 55 верных способов улучшить структуру и код ваших программ

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

Скотт Майерс , Скотт Мейерс

Программирование, программы, базы данных / Программирование / Книги по IT