Расстановка 8 слонов на шахматной доске, при которой каждое поле будет находиться под ударом одного из них

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

Решал с помощью рекурсии. Придумал такой алгоритм: сначала поставить на начальную клетку первого слона и на доске отметить крестиком те поля, которые он бьет, далее то же самое провернуть для второго слона и так далее до 8. После того, как все 8 слонов будут расставлены, нужно проверить, что все клетки биты, если да, то вывести их на экран Функция markBishopMoves как раз должна отмечать все клетки по диагонали как "битые" (ставить на их место символ х) а в функции reshenie - рекурсивно должны расставляться слоны

Как можно решить эту задачу используя рекурсию по-другому? Может, в коде какая то проблема и его можно исправить?

char board[8][8] = { '0' };
bool isOnBoard(int x, int y) {
    return x >= 0 && x < 7 && y >= 0 && y < 7;
}


void markBishopMoves(int x, int y) {
    for (int dx = -1; dx <= 1; dx += 2) {
        for (int dy = -1; dy <= 1; dy += 2) {
            int nx = x + dx, ny = y + dy;
            while (isOnBoard(nx, ny)) {
                if (board[nx][ny] != 'x' || board[nx][ny] != 'B') {
                    board[nx][ny] = 'x';
                }
                nx += dx;
                ny += dy;
            }
        }
    }
}
void reshenie(int x, int y, int count) {
    if (count == 8) {
        bool flag = true;
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (board[i][j] == '0')
                    flag = false;
            }
        }
        if (flag) {
            char letters[8] = { 'a','b','c','d','e','f','g','h' };
            for (int i = 0; i < 8; i++) {
                printf("%4c", letters[i]);
            }
            for (int i = 0; i < 8; i++) {
                printf("\n%d", i + 1);
                for (int j = 0; j < 8; j++) {
                    printf("%4c", board[i][j]);
                }
            }
            printf("\n\n");
        }
        return;
    }

    if (y == 7) { 
        x++;
        y = 1;
    }
    markBishopMoves(x, y);
    reshenie(x, y + 1, count+1);
    board[x][y] = 'B';
    markBishopMoves(x, y);
}

int main() {
    reshenie(0, 0, 0);
}

Ответы (1 шт):

Автор решения: MBo

Не ответ, а соображения по уменьшению размерности задачи.

Для контроля доски требуется 4 чернопольных и 4 белопольных слона: 3 слона не могут контролировать все 14 крайних полей своего цвета. Значит, мы можем найти решения для контроля черных полей 4 чернопольными слонами, получить из них решения для белых полей, просто отразив относительно центральной вертикали, и скомбинировать результаты.

Для 4 слонов на 32 полях есть C(32,4)=35960 комбинаций (вариантов расстановки) - это вполне посильное количество для простого перебора с проверкой.

→ Ссылка