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

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

Восстановить пароль Регистрация
Другие темы раздела
C++ Другой алгоритм(более простой) http://www.cyberforum.ru/cpp-beginners/thread237147.html
Призываю к помощи истинных знатоков для решения более простым способом(как я понял без массива и с помощью подпрограмм) данных задач: 1.Дан текст произвольной длины, оканчивающийся точкой с запятой. Подсчитать количество цифр в тексте. #include <iostream.h> #include <string.h> int main(){ int chislo=0; //считает количество цифр int strl; ...
C++ Heap corruption detected: after normal block (#153) at 0x00345730 #ifndef COW_H__ #define COW_H__ class Cow { char name; char *hobby; double weight; static int num;// chislo obektov http://www.cyberforum.ru/cpp-beginners/thread237144.html
5 м/с и 5 км/ч. Что больше? C++
5 м/с и 5 км/ч. что больше? Нужно составить программу С++. Именуйте темы осмысленно. Название темы должно максимально полно отражать ее содержание.
В чем ошибка? C++
Здраствуйте читаю книгу Джесса Либерти С++ за 21 день, там вот такая функция: функция которая принимает два целочисленных параметра и возвращает целочисленное значение. #include <iostream> using namespace std; int Add (int x, int y) { cout <<"In Add(),received "<<x << "and "<< y <<"\n"; } int main() {
C++ Почему массив не переполняется? http://www.cyberforum.ru/cpp-beginners/thread237087.html
Вот в одной книге есть задание создать вектор и скопировать элементы в массив. Почему массив не переполняется в следующем коде, какая-то загадка для меня. Вроде бы после введения 2-3 элементов он не должен больше принимать, а он принимает, и только после введения 6 элементов программа завершается с ошибкой, а 5 спокойно запоминает, ладно бы вектор, а тут массив, вроде бы с определенным размером:...
C++ Чётные слова в строке Ввести строку. На экран вывести все чётные слова. #include "StdAfx.h" #include<conio.h> #include <ctime> #include <iostream> #include <math.h> #include <string> using namespace std; подробнее

Показать сообщение отдельно
4ance
1 / 1 / 0
Регистрация: 02.11.2010
Сообщений: 78
02.02.2011, 18:03     Минимальный проход коня по доске
Решаю задачу с условием:
Найти возможные способы для удара конём максимального количества вражеских фигур за 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 пункта.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 22:53. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru