8 ферзей на шахматной доске – 12 решений. 8 ферзей


8 ферзей на шахматной доске - 12 решений

Одной из отличных задач-головоломок является 8 ферзей на шахматной доске. Эта игра была придумана еще в 1848 году известным шахматистом Базелем Максимом. Если вы хотите заняться саморазвитием и планируете начать с шахмат, то эта задача станет отличным стартом.

как-расставить-восемь-ферзей-на-шахматной-доске

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

Варианты решения задачи

На сегодняшний день существует 12 решений, однако если применять правила симметрии, то насчитывается целых 92 варианта. Первое решение этой головоломки было опубликовано уже через два года Францом Наке. После него еще большое количество ученых и любителей пытались найти свое собственное решение как поставить 8 ферзей на шахматной доске. Например, всемирно известный математик и физик Гаусс нашел 72 варианта размещения фигур на шахматной доске. Такое количество вариантов было обусловлено интересным подходом – ученый разворачивал доску поочередно на 90, потом на 180 и на 270 градусов. Таким образом, получая новые комбинации.

192_1 127972

Расставить 8 ферзей на шахматной доске непросто, однако каждый сможет найти хотя бы одно верное решение практически сразу. Одним из наиболее известных решений является такое расположение фигур:h5, f1,d8,b4,g7,e3,c6,a2. Еще три варианта решения можно наблюдать, если развернуть шахматную доску, подобно решению Гаусса.

b51306223d9296214dbc2e82c1adb0d3

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

Читайте также:

levico.ru

Задача «8 ферзей» | Блог 4brain

«8 ферзей» – отличная задача-головоломка для развития логического мышления. Эта online флеш-игра является своеобразной современной формулировкой известной шахматной задачи, придуманной шахматистом Максом Базелем в 1848 г.

Любители шахмат наверняка слышали об этой самой популярной математической игре на шахматной доске. Поиск ответа на вопрос о том, как же все-таки расставить 8 ферзей в этой задаче, будет полезным для всех, кто хочет развивать свои интеллектуальные способности, находить решения нестандартных задач, продумывать ходы в поисках ответа.

Правила. Задача о 8 ферзях имеет своим единственным условием задание расставить на стандартной шахматной доске (64 клетки, 8х8) 8 фигур – ферзей, (или королев, если угодно), таким образом, чтоб ни одна из них не была под боем другой.

Вспоминается фраза из «Трех мушкетеров» Дюма, отпущенная Ришелье во время игры в шахматы с д’Артаньяном: «Это королева, она ходит как угодно». Эта цитата хоть в конкретном случае и была двойственной, но все же она для тех, кто незнаком с правилами игры в шахматы. Уточним, что ферзь ходит на любое поле по вертикали, горизонтали и диагонали, на любые расстояния.

Полезные советы или в поисках решения

Всего оригинальных решений 12. Общее количество возможных (с учетом применения операции симметрии) вариантов – 92. Первым опубликовал ответ на эту задачу в 1850 г. Франц Нак. С тех пор многие ученые решали и исследовали эту задачу, предлагая собственные варианты решения. Так, известный немецкий математик, механик и физик Карл Гаусс очень любил эту головоломку и находил 72 варианта возможной расстановки. Он творчески подошел к процессу поиска ответа – разные комбинации 8 ферзей достигались с помощью интересного приёма… поворота доски на 90, 180 и 270 градусов соответственно. Такое вот нетривиальное решение этой головоломки.

Задача достаточно сложная, но как минимум один вариант как правильно расставить ферзей находится довольно быстро и называется явным. Самое популярное правильное расположение достигается следующей расстановкой ферзей: a2, b4, c6, d8, e3, f1, g7, h5. Схема данной расстановки изображена на первом рисунке, оставшиеся три способа расставить ферзей были найдены при вращении шахматной доски.

Другие комбинации постарайтесь найти самостоятельно. Успехов!

Тренируемые навыки

При поиске ответа на задачу тренируются следующие навыки:

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

Любите подобные загадки, игры, головоломки и тесты? Получите неограниченный доступ ко всем интерактивным материалам на сайте, чтобы развиваться эффективнее.

Отзывы и комментарии

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

4brain.ru

Шахматная игра 8 Ферзей, играть в игры головоломки 8 Queens of Death онлайн

Шахматная игра 8 Ферзей, играть в игры головоломки 8 Queens of Death онлайн

     “8 ферзей” – это интересная игра для любителей головоломок. Идея для игры была подсказана известной логической задачей о расстановке фигур на шахматной доске. По условию задачи требуется расставить на самой обычной 64-клеточной шахматной доске 8 ферзей. Фигуры должны находится таким образом, чтобы ни одна из них не находилась под атакой другой фигуры. Каждый игрок знает, что ферзь или королева – самая сильная шахматная фигура. И не так-то просто разойтись на доске даже двумя ферзями, а в игре предстоит разместить целых восемь фигур! Игроку дана трехмерная доска, на которой с помощью мышки, он может устанавливать фигуры. Нажатием левой кнопки мыши можно установить королеву на любую клеточку поля. Теперь нужно внимательно следить, чтобы после второй установки следующей фигуры, ее линии атаки по горизонтали, вертикали и диагонали не пересекались с предыдущей фигурой. Все очень просто, но и одновременно достаточно сложно, ведь чем больше ферзей появляется на шахматном поле сражений, тем меньше свободного места остается. Если фигура попадет под влияние другого ферзя, то она будет считаться “убитой”. Потренируйте логическое мышление в этой увлекательной и бесплатной головоломке.

Управление: - мышкой. Поделись успехом в соц-сетях: SparkChess Flash III Ultimate Chess Захват флага
8 ферзей Шахматы с компьютером asisChess

© 2014 Игры шахматы, все права принадлежат сайту Shahmaty.net

shahmaty.net

Решение задачи о 8 ферзях

КУРСОВАЯ РАБОТА

Тема:

«Решение задачи о 8 ферзях»

Харьков 2007

Цель работы: разработать программу, которая бы наглядно продемонстрировала варианты размещения ферзей на шахматной доске, удовлетворяя правилам задачи.

Метод исследования: изучение литературы, составление и отладка программ на компьютере, проверка решений.

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

Задача звучит следующим образом:

«Какими способами можно расставить на доске восемь ферзей так, чтобы они не угрожали друг другу, т.е. никакие два не стояли на одной вертикали, горизонтали и диагонали и сколько таких способов?»

Задача о восьми ферзях

Очевидно, больше восьми мирных ферзей (как и ладей) на обычной доске расставить невозможно. Найти какое-нибудь расположение восьми ферзей, не угрожающих друг другу, легко (на рисунке представлены четыре искомые расстановки). Значительно труднее подсчитать общее число расстановок и вывести их, в чем, собственно, и состоит задача.

Любопытно, что многие авторы ошибочно приписывали эту задачу и ее решение самому К. Гауссу. На самом деле, она была впервые поставлена в 1848 г. немецким шахматистом М. Беццелем. Доктор Ф. Наук нашел 60 решений и опубликовал их в газете «Illustrierte Zeitung» от 1 июня 1850 г. Лишь после этого Гаусс заинтересовался задачей и нашел 72 решения, которые он сообщил в письме к своему другу астроному Шумахеру от 2 сентября 1850 г. Полный же набор решений, состоящий из 92 позиций, получил все тот же Ф. Наук. Он привел их в упомянутой газете от 21 сентября 1850 г. Эта хронология установлена известным немецким исследователем математических развлечений В. Аренсом.

Строгое доказательство того, что 92 решения исчерпывают все возможности, было получено лишь в 1874 г. английским математиком Д. Глэшером (при помощи теории определителей). Забегая вперед, отметим, что существенных решений (не совпадающих при отражениях и поворотах доски) имеется только двенадцать.

Известно много способов организовать эффективный поиск расположения восьми мирных ферзей (методы Пермантье, Ла-Ное, Гюнтера, Глэшера, Лакьера и др.). Эти способы описаны в многочисленной литературе по занимательной математике. В наш век ЭВМ задача такого сорта не вызвала бы столь живой интерес. Ведь достаточно составить несложную программу, и уже через несколько минут после ее введения в машину все 92 необходимые позиции будут выданы на печать.

Из каждого решения задачи о ферзях можно получить ряд других при помощи поворотов (вращений) доски на 90, 180 и 270°, а также при ее зеркальном отражении относительно линий, разделяющих доску пополам. Например, из расстановки, показанной на рис. а, при повороте доски на 90° по часовой стрелке мы получаем расстановку на рис. в, а при отражении доски относительно линии, разделяющей королевский и ферзевый фланги, – на рис. г. При помощи других поворотов и отражений доски можно получить еще пять решений.

Итак, указанные операции с шахматной доской позволяют из одного расположения мирных ферзей получить, вообще говоря, семь новых. Доказано, что в общем случае на доске nхn (при n > 1) для любой расстановки n мирных ферзей возможны три ситуации:

1) при одном отражении доски возникает новая расстановка ферзей, а при поворотах и других отражениях новых решений не получается;

2) новое решение возникает при повороте доски на 90°, а ее отражения дают еще две расстановки;

3) три поворота доски и четыре отражения приводят к семи различным расстановкам (а если считать и исходную, то всего имеем восемь позиций).

В случае 1) исходное решение называется дважды симметрическим, в случае 2) – симметрическим, а в случае 3) – простым. Для обычной доски каждое решение является либо простым, либо симметрическим, а дважды симметрических не существует.

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

1) см. рис. а;

2) см. рис. б;

3) a4, b1, c5, d8, e6, f3, g7, h3;

4) a4, b2, c5, d8, e6, f1, g3, h7;

5) a4, b2, c7, d3, e6, f8, g1, h5;

6) a4, b2, c7, d3, e6, f8, g5, h2;

7) a3, b5, c2, d8, e6, f4, g7, h2;

8) a4, b1, c5, d8, e2, f7, g3, h6;

9) a4, b7, c3, d8, e2, f5, g1, h6;

10) a6, b4, c2, d8, e5, f7, g1, h4;

11) a4, b8, c1, d5, e7, f2, g6, h4;

12) a4, b2, c7, d5, e1, f8, g6, h4.

Остальные 80 расстановок получаются из этих двенадцати при помощи поворотов и отражений доски. Основная расстановка на рис. б является симметрической, другие одиннадцать основных расстановок – простыми. Итак, всего на доске имеем 11·8+1·4=92 расстановки восьми ферзей, не угрожающих друг другу.

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

Всякое решение задачи о восьми ферзях можно записать как набор (t1, t2, ј, t8), представляющий собой перестановку чисел 1, 2, ј, 8. Здесь ti – номер горизонтали, на которой стоит ферзь i-й вертикали. Так как ферзи не стоят на одной горизонтали, то все числа ti различны, а поскольку ферзи не стоят и на одной диагонали, то для любых i, j (i < j Ј 8) имеем: |tj-ti| № j-i.

Запишем числа 1, 2, ј, 8 сначала по возрастанию, а затем по убыванию. После этого сложим числа каждой из этих двух перестановок с числами произвольной перестановки восьми чисел, например такой – (3, 7, 2, 8, 5, 1, 4, 6): 1, 2, 3, 4, 5, 6, 7, 8

+ 3, 7, 2, 8, 5, 1, 4, 6

4,9, 8, 7, 6, 5, 4, 3, 2, 1

+ 3, 7, 2, 8, 5, 1, 4, 6

11,14,8,13,9,4, 6, 7.

Полученные суммы образуют два набора: (4, 9, 5, 12, 10, 7, 11, 14) и (11, 14, 8, 13, 9, 4, 6, 7). Рассмотрим следующую задачу.

Какие перестановки чисел от 1 до 8 дают в результате указанной операции сложения два таких набора, в каждом из которых все элементы различны?

Задача о восьми ферзях привлекла внимание Гаусса именно в связи с этой чисто арифметической задачей. Оказывается, между решениями этих двух задач существует взаимно однозначное соответствие. Другими словами, каждая расстановка восьми ферзей, не угрожающих друг другу, дает решение арифметической задачи, и наоборот. Для выбранной перестановки оба набора состоят из различных чисел, и это не случайно – она соответствует первой основной расстановке (см. рис. а).

Нетрудно видеть, что при поворотах и отражениях доски одни решения получаются из других при помощи простых арифметических операций над координатами полей, занятых ферзями. Анализ этих операций позволяет обнаружить дополнительные свойства решений, которые мы не станем обсуждать.

Задача об n ферзях. На шахматной доске nхn расставить n ферзей так, чтобы они не угрожали друг другу.

На доске 1х1 один ферзь ставится на одно-единственное поле, и решение существует. На доске 2х2 один ферзь, где бы ни стоял, нападает на три других поля, и второго ферзя поставить некуда. На доске 3х3 умещаются только два мирных ферзя. Итак, для досок 2х2 и 3х3 задача не имеет решения. Эти два случая представляют собой исключение. Для всех n > 3 на доске nхn можно расставить n не угрожающих друг другу ферзей.

На доске 4ґ4 существует одна основная расстановка, причем дважды симметрическая: a2, b4, c1, d3, т.е. всего имеется два решения. На доске 5ґ5 основных расстановок две: 1) a2, b4, c1, d3, e5; 2) a2, b5, c3, d1, e4. Общее число расстановок равно десяти, причем из них можно выбрать пять таких, при наложении которых друг на друга 25 ферзей заполняют все поля доски 5х5.

Заметим, что в общем случае n расстановок (решений задачи) могут заполнить при наложении всю доску nхn только при тех n, которые не кратны двум и трем. Из этого, в частности, следует, что для обычной доски подобрать восемь расстановок, накрывающих все 64 поля доски, невозможно.

Обобщая алгебраическое свойство решений задачи о восьми ферзях, получаем, что расстановка n ферзей (t1, t2, ј, tn) на доске nґn является искомой, если для любых i, j (i < j Ј n) имеет место: |tj-ti| № j-i. Таким образом, задача об n ферзях сводится к чисто математической задаче о нахождении перестановки чисел 1, 2, ј, n, удовлетворяющей указанному условию. Известно много решений этой задачи, некоторые из них опубликованы в серьезных математических журналах. Один из методов расстановки n ферзей, не угрожающих друг другу на произвольной доске nґn (n і 5), можно найти в книге «Математика на шахматной доске».

Описание алгоритма и структуры программы:

В данной программе реализован рекурсивный метод решения задачи о 8 ферзях.

У нас имеется функция (int put_queen (int x)), которая ставит очередного ферзя на поле и вызывает саму себя для, того чтобы поставить следующего, если очередного ферзя поставить нельзя, то она возвращает управление в функцию, из которой была вызвана, а та в свою очередь пробует поставить своего ферзя в другое место, и опять рекурсивно вызвать себя. Когда функция ставит последнего ферзя, то результат расстановки выводится пользователю.

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

Для сохранения положения ферзей используется массив из 8 элементов целочисленного типа (int queens[8]). Порядок элемента в этом массиве означает номер ферзя и его x’овую координату, то есть столбец, а его значение – y’овую координату, или строку. Мы используем то свойство, что на одном столбце не могут находиться несколько ферзей.

mirznanii.com

Задачка о восьми ферзях / Хабр

Рассмотрим такую любимую задачу на понимание алгоритмов, как «Задача о восьми ферзях». Классическое определение: «расставить на шахматной доске 8 ферзей так, чтобы ни один из них не бил другого». Ок, задачка очень популярная на разных собеседованиях, и Википедия нам сразу дает решение на моем любимом Python'е.

И это наверняка правильное решение с точки зрения обычного человека, но абсолютно бессмысленное с точки зрения хакера, и вот я вам расскажу почему:

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

И как только алгоритм отработает мы получим все возможные решения.

Так в чем же проблема? В нашем случае, для доски 8х8, мы получим 92 различные решения, а представим, что, как это часто бывает в реальных задачах, мы не знаем размера доски. Если доска будет 25x25, как в тай сёги, тогда количество решений уже будет 275,986,683,743,434.

Таблица, зависимость количества решений от размера доски:

n: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 .. 24 25 26 уникальных: различных:
1 0 0 1 2 1 6 12 46 92 341 1,787 9,233 45,752 .. 28,439,272,956,934 275,986,683,743,434 2,789,712,466,510,289
1 0 0 2 10 4 40 92 352 724 2,680 14,200 73,712 365,596 .. 227,514,171,973,736 2,207,893,435,808,352 22,317,699,616,364,044
Что это будет значить для нашего скрипта? А то, что он уйдет в очень долгий поиск, и так-как все решения ему придется держать в уме, то уже через 15 мин Python будет съедать 300 мегабайтов памяти. Кто обладает мощным процессором и большим объемом оперативной памяти может проверить, завершиться ли этот процесс вообще...

А все, что нам требовалось при решении подобной задачи — подобрать правильный алгоритм обхода графа, которым в нашем случае оказался бы обычный поиск в глубину, тогда обход графа происходил бы в таком порядке:

А код был бы на много проще, и даже бы через 15 мин скрипт съедал бы ровно столько же памяти, как и через секунду после запуска. И вот бы как его реализация выглядела бы на Python'е:

def rc_queens(n_col, width, sol): if len(sol) == width: print sol else: for n_row in range(width): if (safe_queen(n_row, n_col, sol)): rc_queens(n_col+1, width, sol+[n_row]) def safe_queen(new_row, new_col, sol): for col in range(len(sol)): if (sol[col] == new_row or abs(col - new_col) == abs(sol[col] - new_row)): return 0 return 1 if __name__ == "__main__": for n in range(8): rc_queens(1, 8, [n]) P.S. Это всего лишь взгляд на проблему со стороны хакера, может кто-то предложит взгляд со стороны «theoretical computer science»?

habr.com

Задача о 8 ферзях | Основы программирования

screen

Наиболее известная задача о шахматных расстановках. Требуется расставить 8 ферзей на шахматной доске таким образом, чтобы они не били друг друга.

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

void main() { #include <stdlib.h> #include <gtk/gtk.h> #include <gdk/gdkkeysyms.h> #include <../cairo/cairo.h>   /*Размеры окна */   #define WIDTH 720 #define HEIGHT 700   /*Количество ферзей*/ #define N 8   // ->> Обьявление функций gboolean Draw ( GtkWidget*, GdkEventExpose*, gpointer ); gboolean KeyPress ( GtkWidget*, GdkEventKey*, gpointer );   char check ( int* , int ); void print_field ( int* , int ); void build ( int* , int ); // <<-     // ->> Указатели для хранения виджета(окна) и 2 изображений (доски и ферзя) GtkWidget *window = NULL; cairo_surface_t *background = NULL; cairo_surface_t *queen = NULL; // <<-   // ->> Максимальное количество вариантов и текущий просматриваемый вариант расстановки int MaxNumber = 0; int CurrentVariant = 0; // <<-   // ->> Двумерный массив хранения координат по X для каждого из 92 случаев для 8 ферзей и строка вывода собщения int AllPos[93][8]; char MessageString[100 + 1]; // <<-   // ->> Просмотр шахматной доски и проверка, не находится ли поле под боем char check ( int *A, int n ) { int i,j; for (i = 0; i < n; i++) for (j = 0; j < n; j++) { if ( ( A[i] == A[j] ) && ( i != j ) && ( A[i] != 0 ) ) return 0; if ( ( ( A[i] + i ) == ( A[j] + j ) ) && ( i != j ) && ( A[i] != 0 ) && ( A[j] != 0 ) ) return 0; if ( ( ( A[i] - i ) == ( A[j] - j ) ) && ( i != j ) && ( A[i] != 0 ) && ( A[j] != 0 ) ) return 0; } return 1; }   void print_field ( int *A, int n ) { int i,j; for (i = 0; i < n; i++) { for( j = 0; j < n; j++) printf("--"); printf("-\n"); for (j = 1; j < A[i]; j++) printf("| "); printf("|F"); //Записываем расположениt ферзя по X координате   AllPos[MaxNumber][i] = A[i];   for (j = A[i]; j < n; j++) printf("| "); printf("|\n"); } for(j = 0; j < n; j++) printf("--"); printf("-\n\n"); //Увеличиваем кол-во вариантов MaxNumber++; }     void build ( int *A, int n ) { int *B; int i,k; for( k = 0; ( A[k] != 0 ) && ( k < n ); k++ ); if( k >= n ) { print_field ( A, n ); return; } B = (int *) malloc( n * sizeof(int) ); for ( i = 0; i < k; i++ ) B[i] = A[i]; for ( i = k; i < n; i++ ) B[i] = 0;   for ( i = 1; i <= n; i++ ) { B[k] = i; if ( check ( B, n ) ) build ( B, n ); } free( B ); }     int main ( int argc, char *argv[] ) { gtk_init (&argc, &argv); //Инициализируем GTK+   window = gtk_window_new (GTK_WINDOW_TOPLEVEL); //Создаём окно поверх остальных созданных gtk_window_set_title (GTK_WINDOW (window), "Queen Algorithm"); //Устанавливаем заголовок окна   background = cairo_image_surface_create_from_png ( "image/bg.png" ); //Открываем изображение доски queen = cairo_image_surface_create_from_png ( "image/queen.png" ); //Открываем изображение ферзя   gtk_widget_set_size_request ( window, WIDTH, HEIGHT ); //Устанавливаем размеры окна gtk_window_set_resizable ( GTK_WINDOW ( window ), FALSE ); //Запрещаем возможность растяжения окна   gtk_window_set_position ( GTK_WINDOW ( window ), GTK_WIN_POS_CENTER ); //Устанавливаем окно по-середине экрана gtk_widget_realize ( window );   /* ->> Создаём 3 события: 1 - проверяет закрыто ли окно, в случае закрытия вызывает функцию остановки главного цикла GTK 2 - События прорисовки экрана, требуется для прорисовки изображения 3 - Событие, отслеживающее нажатие клавиши */ g_signal_connect ( window, "destroy", gtk_main_quit, NULL ); g_signal_connect ( window, "expose-event", Draw, NULL ); g_signal_connect ( window, "key_press_event", KeyPress, NULL ); // <<-   gtk_widget_show_all ( window ); //Отображаем наше окно   //построение int A[N]; int i; for ( i = 0; i < N; i++) A[i] = 0;   build(A, N); char str[] = "Resheniy: %i "; printf(str, MaxNumber); // <<-   gtk_main (); //Запускаем главный, бесконечный цикл GTK   /* ->> После срабатывания события закрытия окна, выключается главный цикл, после чего мы уничтожаем в оперативной памяти изображения, которые были открыты ранее (Доска и ферзь) */ cairo_surface_destroy ( background ); cairo_surface_destroy ( queen ); // <<- return 0; }     // ->> Функция вызывается после срабатывания события нажатия клавиши // ->> Параметры: 1 - виджет, в котором сработало событие - т.е. наше окно // ->> 2 - Параметры самого события // ->> 3 - Данные, передаваемые в функцию, но здесь они в принципе не нужны, т.к. мы ничего не передаём gboolean KeyPress ( GtkWidget *wid, GdkEventKey *event, gpointer data ) { //Проверка, какая клавиша была нажата.. switch( event->keyval ) { //Если клавиша в право или D - показать след. вариант расстновки case GDK_Right: case GDK_d:   printf("Right is pressed\n"); //Проверка, что если мы дошли до конца списка возможных вариантов расстановки - то начать заного if( ++CurrentVariant >= MaxNumber ) CurrentVariant = 0; //Стереть текущее расположение изображение в окне gtk_widget_queue_clear(wid);   break; //Если влево или A - предыдущий case GDK_Left: case GDK_a:   printf("Left is pressed\n"); //Тут аналогично if( --CurrentVariant < 0 ) CurrentVariant = MaxNumber - 1; //Стереть текущее расположение изображение в окне gtk_widget_queue_clear(wid);   break; }   return TRUE; }   //Функция вызывается при прорисовке изображений внутри окна, параметры те же, что и в предыдущей функции gboolean Draw ( GtkWidget *wid, GdkEventExpose *event, gpointer data ) { cairo_t *cr ; //Создаём область для рисования в окне cr = gdk_cairo_create ( wid->window ); //Рисуем изображение шахматной доски в координатах (0.0) cairo_set_source_surface ( cr, background, 0, 0 ); //Рисуем... cairo_paint ( cr ); //Циклом прогоняем все 8 ферзей, и каждый рисуем в соответствии с координатами умноженными на масштаб, т.к. область рисования у нас не единичная int i; for(i = 0; i < N; i++) { cairo_set_source_surface ( cr, queen, 90 * AllPos[CurrentVariant][i] - 90 + 3, i * 90 + 4 ); cairo_paint ( cr ); } //Формируем строку вывода вариантов sprintf(MessageString, "Current Variant: %d, Max: %d", CurrentVariant + 1, MaxNumber); //Устанавливаем цвет текста, его размер, и месторасположение cairo_set_source_rgb(cr, 1.0, 0.8, 0.2); cairo_set_font_size(cr, 20); cairo_move_to(cr, 10, HEIGHT - 10); //Выводим текст cairo_show_text(cr, MessageString); //Удаляем область рисования cairo_destroy ( cr );     return TRUE; }     }

Ключевые слова: 

8 ферзей, шахматные расстановки, gtk+, с/с++ ВложениеРазмер
Chess.rar1.17 Мб

www.opita.net

задача о 8 ферзях | C++ для приматов

#include <iostream>

#include <stdio.h>

#include<fstream>

using namespace std;

 

const int n = 8;// Размер поля

int count_test = 0;// Количество тестов

int mincountstep = n + 1; //Количество ходов

int frtest[n]; //расстановка теста

int fr[n]; //правильная расстановка

 

bool check(int nf)

// проверка битых полей

{

if ( fr[nf] < 0 )  return false; //На всякий случай, чтобы не проверять поля где нет ферзей

    for (int i = 0; i < n && fr[i] >= 0; i++) {          

        if ( i == nf ) continue;

        if (fr[nf] == fr[i]  ) return false;  // (Горизонталь)

        if ( (nf + fr[nf]) ==  (i + fr[i]) ) return false; // Нисходящая диагональ

        if ( (nf - fr[nf]) ==  (i - fr[i]) ) return false; // Восходящая диагональ

    }  

    return true; //если поле свободно

}

 

void calc_min_strok()

// Вычисление количества ходов и нахождение минимального

{

   int countstep = 0; // количество ходов

   for (int i = 0; i < n; i++){

      if ( frtest[i] != fr[i] ) countstep++;

   }

   if ( mincountstep > countstep ) mincountstep = countstep;

 

}

 

bool line_up(int i)

//рекурсивня функция установки ферзей (стек расстановок)

{

    if ( i > n-1) return false ;

    for (int j = 0; j < n; j++) {

        fr[i] = j;

        if ( check(i) == true ) {              

            if ( i == n-1) { //Если дошли до последней колонки и всё хорошо

            calc_min_strok();

            } else {

                line_up(i+1);

            }

        }

        fr[i] = -1 ;  

    }

  return false ;

}

 

int main()

{

cin >> count_test;

//Обнуление начального массива

for (int test = 0; test < count_test; test++ ){

   mincountstep = n + 1;

       for (int i = 0; i < n; i++) fr[i] = -1;

       //ввод данных теста

   for (int i = 0; i < n; i++) {    

         cin >> frtest[i];  

    frtest[i]--;    

   }

       line_up(0);    

       cout << mincountstep;

}  

    

    return 0;

}

cpp.mazurok.com