БлогNot. Задача о мирных ферзях

Задача о мирных ферзях

Так как верный результат мной сейчас не получен, в коллекцию задач на шахматной доске заметка пока не пойдёт, а суть проблемы состоит вот в чём:

Мирно сосуществующие армии ферзей.

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

Теоретическим решениями должна соответствовать последовательность A250000, но показанная ниже программка не находит расстановки максимально допустимого количества ферзей для некоторых размерностей доски (8, а также от 10 и выше).

Кто найдёт решение проблемы - тому конфетка, может, начинать поиск нужно иначе. Программка тестировалась в консоли Visual Studio 2019.

#include <iostream>
#include <vector>
using namespace std;

enum class Piece { empty, black, white };
typedef pair <int, int> position;

bool isAttacking (const position &queen, const position &pos) {
 return queen.first == pos.first || queen.second == pos.second || 
        abs(queen.first - pos.first) == abs(queen.second - pos.second);
}

bool place (const int m, const int n, vector<position>& pBlackQueens, vector<position>& pWhiteQueens) {
 if (m == 0) return true;
 bool placingBlack = true;
 for (int i = 0; i < n; i++) {
  for (int j = 0; j < n; j++) {
   auto pos = make_pair(i, j);
   for (auto queen : pBlackQueens) {
    if (queen == pos || !placingBlack && isAttacking(queen, pos)) goto next_step;
   }
   for (auto queen : pWhiteQueens) {
    if (queen == pos || placingBlack && isAttacking(queen, pos)) goto next_step;
   }
   if (placingBlack) {
    pBlackQueens.push_back(pos);
    placingBlack = false;
   }
   else {
    pWhiteQueens.push_back(pos);
    if (place(m - 1, n, pBlackQueens, pWhiteQueens)) {
     return true;
    }
    pBlackQueens.pop_back();
    pWhiteQueens.pop_back();
    placingBlack = true;
   }
   next_step: ; //т.к. выходим из вложенного цикла
  }
 }
 if (!placingBlack) pBlackQueens.pop_back();
 return false;
}

void printBoard (int n, const vector<position> &blackQueens, const vector<position> &whiteQueens) {
 vector <Piece> board (n * n);
 fill (board.begin(), board.end(), Piece::empty);
 for (auto& queen : blackQueens) board[queen.first * n + queen.second] = Piece::black;
 for (auto& queen : whiteQueens) board[queen.first * n + queen.second] = Piece::white;
 for (size_t i = 0; i < board.size(); ++i) {
  if (i != 0 && i % n == 0) cout << endl;
  switch (board[i]) {
  case Piece::black:
   cout << "B ";
  break;
  case Piece::white:
   cout << "W ";
  break;
  case Piece::empty:
  default:
   int j = i / n;
   int k = i - j * n;
   if (j % 2 == k % 2) {
    cout << "x ";
   }
   else {
    cout << "* ";
   }
   break;
  }
 }
 cout << endl << endl;
}

int main() {
 vector <position> nms = { //какие доски проверить: размерность, количество ферзей
   {1,0}, {2,0}, {3,1}, {4,2}, {5,4}, {6,5}, {7,7},
   {8,9}, {9, 12}, {10,14}, {11,17}, {12,21}
 };
 for (auto nm : nms) {
  cout << nm.second << " black and " << nm.second << " white queens on a " << nm.first << " x " << nm.first << " board:\n";
  vector<position> blackQueens, whiteQueens;
  if (place(nm.second, nm.first, blackQueens, whiteQueens)) {
   printBoard(nm.first, blackQueens, whiteQueens);
  }
  else {
   cout << "No solution found" << endl << endl;
  }
 }
 cin.get();
 return 0;
}

19.01.2020, 14:41 [1436 просмотров]


теги: шахматы c++ ошибка числа алгоритм

К этой статье пока нет комментариев, Ваш будет первым