Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
#1

Минимальный проход коня по доске - C++

02.02.2011, 18:03. Просмотров 930. Ответов 0
Метки нет (Все метки)

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

Делаю с помощью очередей:
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <conio.h>
 
using namespace std;
 
void UnichtojenieFigury( int, int, int, int );
 
int _tmain(int argc, _TCHAR* argv[])
{
    int Doska2[ 8 ][ 8 ], x2, y2, x3, y3, c, d, EnemyNumber = 0, Enemy = 0;
 
    cout << "Nachalnoe polojenie konya na doske - x, y:\n";
    cin >> x2 >> y2;                            //Требует ввода двух пар координат - начальное полложение коня
 
    cout << "Vvedite koli4esctvo vrajeskih figur( maximum figur = 16 ):\n";    // Количество вражеских фигур
    while ( (  EnemyNumber > 16 ) || (  EnemyNumber <= 0 ) )        // Проверка на правильность ввода
        cin >> EnemyNumber;     
 
    for ( c = 0; c < 8; c++ )
    {
        for ( d = 0; d < 8; d++ )
        {
            Doska2[ c ][ d ] = -1;        // Заполняет матрицу значением -1
        }
    } 
    Doska2[ x2 ][ y2 ] = 0;
 
    srand( time( 0 ) ); // Рандомно расставляем врагов по шахматному полю           
    while ( Enemy < EnemyNumber )
    {
        x3 = rand() % 8;
        y3 = rand() % 8;
        if ( ( Doska2[ x3 ][ y3 ] == -1 ) && ( Doska2[ x3 ][ y3 ] != 99 ) && ( Doska2[ x3 ][ y3 ] != 0 ) )
        {
            Doska2[ x3 ][ y3 ] = 99;
            Enemy++;
        }
    }
 
    cout << "Nachalnoe polojeniya konya i vrajeskih figur:\n" << endl;    // начальное положение коня и вражеских фигур
    for ( c = 0; c < 8; c++ )
    {
        for ( d = 0; d < 8; d++ )
        {      
            printf( "%3d ",  Doska2[ c ][ d ] );
        }
        cout << '\n' << endl;
    } 
    cout << '\n' << endl;
 
//////////////////////////////////////////// РЕШЕНИЕ
 
    for ( c = 0; c < 8; c++ )
    {
        for ( d = 0; d < 8; d++ ) 
        {
            if ( Doska2[ c ][ d ] == 99 )
            {
                UnichtojenieFigury(x2, y2, c, d);
                break;
            }       
        }
        if ( Doska2[ c ][ d ] == 99 )
            break;
    }
    _getch();
    return 0;
}
 
void UnichtojenieFigury( int x, int y, int x1, int y1 )
{
    int Doska[ 8 ][ 8 ], i, j, a, b, Start, Last;
    int Queue[ 2 ][ 64 ];
 
    for ( i = 0; i < 8; i++ )
        for ( j = 0; j < 8; j++ )
            Doska[ i ][ j ] = -1;        // Заполняет матрицу значением -1                         
 
    Doska[ x ][ y ] = 0;        // Клетка начала пути
    Queue[ 0 ][ 0 ] = x;        // Заносит в очередь координату Х начальной клетки
    Queue[ 1 ][ 0 ] = y;        // Заносит в очередь координату Y начальной клетки
    Start = 0;                    // Начальная позиция левого указателя
    Last = 1;                    // Начальная позиция правого указателя
 
    // Запускаем цикл, который продолжает работу до тех пор,
    // пока очередь не пуста или искомый конечный элемент не помечен
    while ( ( Start != Last ) && ( Doska[ x1 ][ y1 ] == -1 ) )
    {
        a = Queue[ 0 ][ Start ];    // Запоминает координату Х текущей клетки
        b = Queue[ 1 ][ Start ];    // Запоминает координату Y текущей клетки
 
        /* Следующие 8 операторов if перебирают все возможные ходы коня,
        предусматривая возможность выхода за пределы поля, и если клетка, в которую можно пойти, 
        не помечена, то ее координаты заносятся в очередь,
        а она сама помечается увеличенной на единицу меткой клетки,
        из которой мы попали в текущую */ 
        cout << endl;
        if ( ( Doska[ a + 2 ][ b - 1 ] == -1 ) && ( a + 2 < 8 ) && ( b - 1 < 8 ) && ( a + 2 > 0 ) && ( b - 1 > 0 ) )
        {
            Queue[ 0 ][ Last ] = a + 2;
            Queue[ 1 ][ Last ] = b - 1;
            Last++;
            Doska[ a + 2 ][ b - 1 ] = Doska[ a ][ b ] + 1;
        }
        if ( ( Doska[ a + 2 ][ b + 1 ] == -1 ) && ( a + 2 < 8 ) && ( b + 1 < 8 ) && ( a + 2 > 0 ) && ( b + 1 > 0 ) )
        {
            Queue[ 0 ][ Last ] = a + 2;
            Queue[ 1 ][ Last ] = b + 1;
            Last++;
            Doska[ a + 2 ][ b + 1 ] = Doska[ a ][ b ] + 1;
        }
        if ( ( Doska[ a - 2 ][ b + 1 ] == -1 ) && ( a - 2 < 8 ) && ( b + 1 < 8 ) && ( a - 2 > 0 ) && ( b + 1 > 0 ) )
        {
            Queue[ 0 ][ Last ] = a - 2;
            Queue[ 1 ][ Last ] = b + 1;
            Last++;
            Doska[ a - 2 ][ b + 1 ] = Doska[ a ][ b ] + 1;
        }
        if ( ( Doska[ a - 2 ][ b - 1 ] == -1 ) && ( a - 2 < 8 ) && ( b - 1 < 8 ) && ( a - 2 > 0 ) && ( b - 1 > 0 ) )
        {
            Queue[ 0 ][ Last ] = a - 2;
            Queue[ 1 ][ Last ] = b - 1;
            Last++;
            Doska[ a - 2 ][ b - 1 ] = Doska[ a ][ b ] + 1;
        }
        if ( ( Doska[ a - 1 ][ b + 2 ] == -1 ) && ( a - 1 < 8 ) && ( b + 2 < 8 ) && ( a - 1 > 0 ) && ( b + 2 > 0 ) )
        {
            Queue[ 0 ][ Last ] = a - 1;
            Queue[ 1 ][ Last ] = b + 2;
            Last++;
            Doska[ a - 1 ][ b + 2 ] = Doska[ a ][ b ] + 1;
        }
        if ( ( Doska[ a + 1 ][ b + 2 ] == -1 ) && ( a + 1 < 8 ) && ( b + 2 < 8 ) && ( a + 1 > 0 ) && ( b + 2 > 0 ) )
        {
            Queue[ 0 ][ Last ] = a + 1;
            Queue[ 1 ][ Last ] = b + 2;
            Last++;
            Doska[ a + 1 ][ b + 2 ] = Doska[ a ][ b ] + 1;
        }
        if ( ( Doska[ a + 1 ][ b - 2 ] == -1 ) && ( a + 1 < 8 ) && ( b - 2 < 8 ) && ( a + 1 > 0 ) && ( b - 2 > 0 ) )
        {
            Queue[ 0 ][ Last ] = a + 1;
            Queue[ 1 ][ Last ] = b - 2;
            Last++;
            Doska[ a + 1 ][ b - 2 ] = Doska[ a ][ b ] + 1;
        }
        if ( ( Doska[ a - 1 ][ b - 2 ] == -1 ) && ( a - 1 < 8 ) && ( b - 2 < 8 ) && ( a - 1 > 0 ) && ( b - 2 > 0 ) )
        {
            Queue[ 0 ][ Last ] = a - 1;
            Queue[ 1 ][ Last ] = b - 2;
            Last++;
            Doska[ a - 1 ][ b - 2 ] = Doska[ a ][ b ] + 1;
        }
        Start++;    // Удаляет первый элемент из очереди
    }
    cout << Doska[ x1 ][ y1 ];
}
Код пока не законченный - функция считает только минимальное количество ходов до первого попавшегося врага( не до самого ближнего - а какой встречается первый компилятору по матрице - слева-направо и сверху-вниз).
Можно из цикла убрать брэйки и подсчитать общее количество ходов от начальной позиции коня до последнего врага. ( при каждом новом вызове функции позиция побитого врага будет считаться начальной позицией коня для следующего вызова) Это пока делать не стал, потому что так я посчитаю один из возможных вариантов - но не минимальный ( минимальность шагов есть только в функции от начальной точки до цели)
Вопрос такой - как найти минимальность именно покрытия всех вражеских фигур.

Добавлено через 6 часов 49 минут
Правильна ли будет такая логика:

Создаю 3 фигуры в рандомном месте.
1) Запускаю функцию хода коня от начальной клетки до фигуры 1, запоминаю количество шагов для этого действия.
2) Конь ходит от фигуры 1 к фигуре 2. Кол-во шагов плюсуется с предыдущем действием.
3) Конь ходит от фигуры 2 к фигуре 3. Кол-во шагов плюсуется с предыдущим.
4) Ход: фигура 1 - фигура 3. Шаги плюсуются с шагом первого пункта.
5) Ход: фигура 3 - фигура 2. Шаги плюсуются с шагами 4го пункта.
6) Запоминаю первое промежуточное значение шагов - минимальное от 5го и 3го пункта(тут не знаю - следует ли это делать)

7) Ход: Начало - фигура 2
8) Ход: фигура 2 - фигура 3
9) Ход: фигура 3 - фигура 1. Шаги 7, 8, 9 - плюсуются
10) Ход: фигура 2 - фигура 1
11) Ход: фигура 1 - фигура 3. Шаги 7, 10, 11 - плюсуются
12) Второе промежуточное значение шагов - минимальное от 9 пункта и 11 ( тот же вопрос что и в 6м пункте)

13) Ход: начало - фигура 3
14) Ход: фигура 3 - фигура 1
15) Ход: фигура 1 - фигура 2. Шаги 13, 14, 15 плюсуются
16) Ход: фигура 3 - фигура 2
17) Ход: фигура 2 - фигура 1. Шаги 13, 16, 17 - плюсуются
18) Третье промежуточное значение шагов - минимальное от 15 пункта и 17 ( тот же вопрос что и в 6м пункте)
19) минимальное от 6, 12 и 18 пункта.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.02.2011, 18:03
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Минимальный проход коня по доске (C++):

Передвижение коня по доске и сбор букв - C++
Добрый день! Не могу разобраться, в чём проблема =( Нужно решить задачу: есть шахматная доска. На ней, в каждой клетке,...

Ход коня по шахматной доске случайным образом - C++
Используйте генерацию случайного числа для предоставления коню возможности ходить по шахматной доске случайным образом (конечно, только ...

Движение по шахматной доске коня (с левого нижнего угла в верхний правый угол) - C++
Шахматная фигура «конь» перемещается на 1 клетку по горизонтали и на 2 клетки по вертикали или на 2 клетки по горизонтали и 1 - по...

Проход по лабиринту - C++
Привет всем. Помогите пожалуйста с задачей на С/C++ идёт практика я не понимаю как сделать задачу просто даже не представляю училка...

Проход по лабиринту - C++
Описать класс, реализующий стек. Написать программу, использующую этот класс для отыскания прохода по лабиринту. Лабиринт...

Проход по квадрату - C++
Вот такая задачка! Помогите чем можете!!!!!! Пройдите в квадрате от клеточки 1 к клеточке 2 так, чтобы посетить все клеточки по одному...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.02.2011, 18:03
Привет! Вот еще темы с ответами:

Проход по массиву - C++
Всем здравствуйте, что то я сейчас затормозил. В общем суть задачки проста найти из данного массива (действительных чисел) первое число...

Проход лабиринта в C++ - C++
Ребята, помогите...вобщем, необходимо пройти по лабиринту и найти самый короткий маршрут...лабиринт я создал, а как пройти по нему ума не...

mpl проход по элементам - C++
Пытался написать вывод элементов vector_c не через for_each. Не вышло. Кто подскажет как сие сделать наиболее удобно? Пример вектора. ...

Ход коня - C++
Здравствуйте, уважаемые форумчане!!! у меня возникла проблема с задачей про коня!!! Дело в том что первоначальные значения координат...


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

Или воспользуйтесь поиском по форуму:
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru