Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.68/34: Рейтинг темы: голосов - 34, средняя оценка - 4.68
0 / 0 / 0
Регистрация: 20.12.2016
Сообщений: 5

Нужно написать программу для расстановки 5 ферзей на шахматной доске

20.12.2016, 11:36. Показов 7178. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужно написать программу для расстановки 5 ферзей на шахматной доске,чтобы эти 5 ферзей били всё поле и вывести число вариантов расстановки без повторений. Не могли бы вы помочь с решением данной задачи,голова совсем не соображает. Понимаю,что нужно создать массив и 64 элементов,массив из 5 элементов,но как расставить этих ферзей в массив и проверить диагонали я ни б ни м. Не могли бы вы помочь разобраться во всем этом,пояснить и разъяснить всё.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.12.2016, 11:36
Ответы с готовыми решениями:

Перечислить все расстановки N ферзей на шахматной доске NxX, при которых они не бьют друг друга
Задача: Перечислить все расстановки N ферзей на шахматной доске NxX, при которых они не бьют друг друга Есть на Paskal решение, как бы...

Расстановка ферзей на шахматной доске
Найти на кубической доске всевозможные расстановки 15 ферзей так, чтобы они не били друг друга

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

11
365 / 321 / 219
Регистрация: 21.02.2013
Сообщений: 756
20.12.2016, 13:26
если без числа вариантов для расстановки то:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <vector>
using namespace std;
struct Ferz{
int x;
int y;
Ferz(int i, int j):x(j), y(i){}
};
void underfire(bool flags[8][8], int i, int j){
        for(int k = 0; k != 8; k++){
                flags[i][k] = false;
                flags[k][j] = false;
        }
        for(int k = i, l = j ; k < 8 && l < 8; k++, l++){
                flags[k][l] = false;
        }
        for(int k = i, l = j ; k >= 0 && l >= 0; k--, l--){
                flags[k][l] = false;
        }
        for(int k = i, l = j ; k < 8 && l >= 0; k++, l--){
                flags[k][l] = false;
        }
        for(int k = i, l = j ; k >= 0 && l < 8; k--, l++){
                flags[k][l] = false;
        }
 
}
bool isFerz(vector<Ferz*> &vec, int& i, int & j){
    for(vector<Ferz*>::size_type st = 0; st != vec.size(); st++){
                    if(i == vec[st]->y && j == vec[st]->x)
                    return true;
                }
                return false;
 
}
void printfield (bool flags[8][8], vector<Ferz*> &vec){
    for(int i = 0; i != 8; i++){
        for(int j = 0; j != 8; j++){
                if(isFerz(vec, i, j))
                cout << 'f' << ' ';
                else cout << '.' << ' ';
        }
            cout << endl;
        }
 
}
void init(bool flags[8][8]){
for(int i = 0; i != 8; i++)
        for(int j = 0; j != 8; j++)
        flags[i][j] = true;
 
}
 
int main()
{
    bool flags[8][8];
    init(flags);
 
    Ferz* f;
    vector<Ferz*> vec;
 
    for(int i = 0; i != 8; i++){
        for (int j = 0; j != 8; j++){
            if(flags[i][j]){
                f = new Ferz(i,j);
                vec.push_back(f);
                underfire(flags, i, j);
            }
        }
    }
    printfield(flags, vec);
}
1
 Аватар для Praktolock
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 356
20.12.2016, 13:28
А зеркальные и повернутые одинаковые расстановки считаются за разные варианты?

Добавлено через 35 секунд
jurok_85, только собрался заняться =(
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
20.12.2016, 13:54
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
 
const int NUM = 5;        // количество ферзей
const int BOARD_SIZE = 8; // размер поля
using Board = bool[BOARD_SIZE][BOARD_SIZE];
 
void PrintBoard(const Board brd)
{
    for (int i=0; i < BOARD_SIZE; i++)
    {
        for (int j=0; j < BOARD_SIZE; j++)
            std::cout << (brd[i][j] ? 'X' : ' ');
        std::cout << std::endl;
    }
}
 
bool BeatAll(const int arr[NUM])
{
    Board board = {};
    // проставляем на поле места, которые бьют наши ферзи
    for (int i=0; i < NUM; i++)
    {
        const int xCoord = arr[i] / BOARD_SIZE, yCoord = arr[i] % BOARD_SIZE;
        // горизонталь
        for (int j=0; j < BOARD_SIZE; j++)
            board[xCoord][j] = true;
        // вертикаль
        for (int j=0; j < BOARD_SIZE; j++)
            board[j][yCoord] = true;
        // главная диагональ
        for (int j = xCoord, k = yCoord; j >=0 && k >= 0; j--, k--)
            board[j][k] = true;
        for (int j = xCoord + 1, k = yCoord + 1; j < BOARD_SIZE && k < BOARD_SIZE; j++, k++)
            board[j][k] = true;
        // побочная диагональ
        for (int j = xCoord, k = yCoord; j >=0 && k < BOARD_SIZE; j--, k++)
            board[j][k] = true;
        for (int j = xCoord + 1, k = yCoord - 1; j < BOARD_SIZE && k >= 0; j++, k--)
            board[j][k] = true;
    }
 
    // for test
    //PrintBoard(board);
 
    // проверяем доску
    for (int i=0; i < BOARD_SIZE; i++)
        for (int j=0; j < BOARD_SIZE; j++)
            if (!board[i][j]) // поле осталось незаполненным
                return false;
    return true;
}
 
int main()
{
    // массив хранит значения от 0 до 63 (номер строки * BOARD_SIZE + номер столбца)
    int arr[NUM], counter = 0;
    // заполняем начальными значениями
    for (int i=0; i < NUM; i++)
        arr[i] = i;
    // перебор всех комбинаций
    do
    {
        if (BeatAll(arr))
        {
            for (int j=0; j < NUM; j++)
            {
                std::cout << '(' << arr[j] / BOARD_SIZE << ", " << arr[j] % BOARD_SIZE << ") ";
                //std::cout << arr[j] << " ";
            }
            std::cout << std::endl;
            counter++;
        }
        arr[NUM - 1]++;
        for (int j = NUM - 1; j >= 1; j--)
            if (arr[j] == BOARD_SIZE * BOARD_SIZE)
            {
                arr[j-1]++;
                arr[j] = arr[j-1]-1;
            }
    } while (arr[0] != BOARD_SIZE * BOARD_SIZE);
 
    std::cout << "\nCounter: " << counter << std::endl;
}
Добавлено через 3 минуты
jurok_85, в вашем варианте ферзи не бьют все поле, да и находит только один вариант.
1
365 / 321 / 219
Регистрация: 21.02.2013
Сообщений: 756
20.12.2016, 14:16
MrGluck, ну ферзи то бьют всё поле, а вариант только один согласен
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
20.12.2016, 14:20
В моём коде есть нюанс с переходом разряда (78 строчка). Возможно, мы получим повторную комбинацию, но мне уже не охота дальше возиться.
Есть 100% вариант - перебирать вообще все комбинации, сортировать их и складывать в какой-нибудь контейнер без повторений, но такой вариант будет намного дольше работать и производить ненужные итерации.
Вообщем, если есть желание - стоит разобраться с перебором комбинаций.
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
20.12.2016, 15:25
Интересно было бы посмотреть на рекурсивное решение задачи.

Добавлено через 3 минуты
Цитата Сообщение от jurok_85 Посмотреть сообщение
MrGluck, ну ферзи то бьют всё поле, а вариант только один согласен
Когда проверял, скосил по диагонали, был не прав.

Добавлено через 55 минут
Количество комбинаций 4860.

Добавлено через 3 минуты
Лучше конечно поменять принцип "увеличения разряда", но для сдачи пойдет и проверка is_sorted.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <algorithm>
#include <iostream>
 
const int NUM = 5;        // количество ферзей
const int BOARD_SIZE = 8; // размер поля
using Board = bool[BOARD_SIZE][BOARD_SIZE];
 
void PrintBoard(const Board brd)
{
    for (int i=0; i < BOARD_SIZE; i++)
    {
        for (int j=0; j < BOARD_SIZE; j++)
            std::cout << (brd[i][j] ? 'X' : ' ');
        std::cout << std::endl;
    }
}
 
bool BeatAll(const int arr[NUM])
{
    Board board = {};
    // проставляем на поле места, которые бьют наши ферзи
    for (int i=0; i < NUM; i++)
    {
        const int xCoord = arr[i] / BOARD_SIZE, yCoord = arr[i] % BOARD_SIZE;
        // горизонталь
        for (int j=0; j < BOARD_SIZE; j++)
            board[xCoord][j] = true;
        // вертикаль
        for (int j=0; j < BOARD_SIZE; j++)
            board[j][yCoord] = true;
        // главная диагональ
        for (int j = xCoord, k = yCoord; j >=0 && k >= 0; j--, k--)
            board[j][k] = true;
        for (int j = xCoord + 1, k = yCoord + 1; j < BOARD_SIZE && k < BOARD_SIZE; j++, k++)
            board[j][k] = true;
        // побочная диагональ
        for (int j = xCoord, k = yCoord; j >=0 && k < BOARD_SIZE; j--, k++)
            board[j][k] = true;
        for (int j = xCoord + 1, k = yCoord - 1; j < BOARD_SIZE && k >= 0; j++, k--)
            board[j][k] = true;
    }
 
    // for test
    //PrintBoard(board);
 
    // проверяем доску
    for (int i=0; i < BOARD_SIZE; i++)
        for (int j=0; j < BOARD_SIZE; j++)
            if (!board[i][j]) // поле осталось незаполненным
                return false;
    return true;
}
 
int main()
{
    // массив хранит значения от 0 до 63 (номер строки * BOARD_SIZE + номер столбца)
    int arr[NUM], counter = 0;
    // заполняем начальными значениями
    for (int i=0; i < NUM; i++)
        arr[i] = i;
    // перебор всех комбинаций
    do
    {
        if (std::is_sorted(arr, arr + NUM) && BeatAll(arr))
        {
            for (int j=0; j < NUM; j++)
            {
                std::cout << '(' << arr[j] / BOARD_SIZE << ", " << arr[j] % BOARD_SIZE << ") ";
                //std::cout << arr[j] << " ";
            }
            std::cout << std::endl;
            counter++;
        }
        arr[NUM - 1]++;
        for (int j = NUM - 1; j >= 1; j--)
            if (arr[j] == BOARD_SIZE * BOARD_SIZE)
            {
                arr[j-1]++;
                arr[j] = arr[j-1]-1;
            }
    } while (arr[0] != BOARD_SIZE * BOARD_SIZE);
 
    std::cout << "\nCounter: " << counter << std::endl;
}
2
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,984
Записей в блоге: 32
21.12.2016, 06:00
Лучший ответ Сообщение было отмечено qwefunnys как решение

Решение

Цитата Сообщение от MrGluck Посмотреть сообщение
Интересно было бы посмотреть на рекурсивное решение задачи.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const int s=8, c=5;
int x[c], y[c], cnt=0;
 
bool good() {
    for(int i=1; i<=s; i++) for(int j=1; j<=s; j++) {
        bool r = false;
        for(int k=0; k<c; k++)
            if (x[k]==i || y[k]==j || y[k]-x[k]==j-i || y[k]+x[k]==j+i) {r=true; break;}
        if (!r) return false;
    }
    return true;
}
void show() { for(int k=0; k<c; k++) cout<<'('<<x[k]<<','<<y[k]<<") "; cout<<'\n'; }
 
void f(int k) {
    if (k==c) { if (good()) {show(); cnt++;} return; }
    int p = k ? x[k-1]*(s+1)+y[k-1] : 0;
    for(int i=1; i<=s; i++) for(int j=1; j<=s; j++) {
        if (i*(s+1)+j <= p) continue;
        x[k]=i; y[k]=j; f(k+1);
    }
}
int main() { f(0); cout<<"Total amount of variants: "<<cnt; }
(1,1) (1,2) (2,6) (5,1) (6,5)
(1,1) (1,2) (4,6) (5,4) (6,5)
(1,1) (1,2) (4,6) (5,7) (6,5)
(1,1) (1,3) (2,7) (5,2) (7,5)
....................................
(4,8) (5,3) (6,1) (7,2) (8,4)
(5,1) (5,4) (5,5) (5,6) (5,7)
(5,2) (5,3) (5,4) (5,5) (5,8)
Total amount of variants: 4860
http://rextester.com/KYO24636
2
0 / 0 / 0
Регистрация: 20.12.2016
Сообщений: 5
21.12.2016, 07:35  [ТС]
_Ivana, Можешь немного разъяснить строчки кода,ну прокомментировать их,если не сложно)

Добавлено через 14 секунд
А так всем спасибо огромное за помощь!
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
21.12.2016, 09:28
Цитата Сообщение от qwefunnys Посмотреть сообщение
Можешь немного разъяснить строчки кода,ну прокомментировать их,если не сложно)
Суть та жа, что и в моём коде - полный перебор комбинаций (немножко по другому).
Ф-ция good проверяет что ферзи бьют всё поле.
Массивы x и y содержат координаты ферзей.
cnt - счётчик комбинаций.
s - размер поля
c - количество ферзей
Ф-ция show выводит результат (текущие координаты всех ферзей)
Вся работа происходит в ф-ции f, которая перебирает комбинации и расставляет ферзей. Если удалось расставить 5 ферзей и они бьют всё поле - выводим координаты и выходим из рекурсии.
Пробуем подобрать координаты для текущей отметки. Если вышло - добавляем их в массив координат и вызываем рекурсивно функцию, увеличивая переданное число.
2
0 / 0 / 0
Регистрация: 19.03.2020
Сообщений: 1
19.03.2020, 20:39
А можно вопрос по поводу того что передаем в f(), что это ? какая-то метка ?
0
 Аватар для abit
868 / 527 / 148
Регистрация: 03.02.2013
Сообщений: 1,845
15.01.2023, 03:59
я взял доску, за пару минут нашёл что достаточно поставить 5 ферзей вдоль диагонали a2-g8 : на a2, c4, d5, e6, g8
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.01.2023, 03:59
Помогаю со студенческими работами здесь

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

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

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

Реализовать программу по распределению 8 слонов по шахматной доске
Добрый день. Нужно реализовать программу по распределению 8 слонов по шахматной доске, которые не должны друг друга пересекать. Что сделать...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru