125 / 117 / 67
Регистрация: 07.11.2014
Сообщений: 788
1

Проверить правильность расстановки кораблей. Морской бой

27.09.2016, 14:56. Показов 3513. Ответов 18
Метки нет (Все метки)

Есть матрица NxM, где расставлены корабли. Корабли не стоят на краю матрицы, кол-во 4-х клеточных кораблей - 1, 3-х клет. - 2, 2-х клеточных - 3, 1-х - 4
Нужно проверить правильно ли расстановлены и ответить YES,NO;
Матрица заполняется 0 и 1, где 1 это клетка корабля.
Корабли не должны соприкасаться друг с другом и должны быть все корабли(не меньше, не больше),задача взята из книги Динман Максима C++ Освой на примерах.
Там есть первый пример, который очень схож с этой задачей, код не выполняется:
Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <conio.h>
const int N = 8, M = 8;
void Add(int x, int y);
void Test();
void Find();
int Label,p,i,j,a,b;
int Start, Last;
int array[N+2][M+2] = {
    {0,0,0,0,0,0,0,0,0,0},
    {0,1,0,0,1,1,1,0,1,0},
    {0,1,0,1,0,0,0,1,0,0},
    {0,1,0,0,0,1,0,0,0,0},
    {0,1,0,1,1,0,1,1,1,0},
    {0,0,0,0,0,0,0,0,0,0},
    {0,1,1,0,1,1,0,1,1,0},
    {0,0,0,0,0,0,0,0,0,0}};
int Queue[2][N*M];
int main() {
    Start = 0;
    Last = 0;
    Label = 0;
    p = 1;
    do
    {
        Find();
        if (p == 1) Test();
    } while (p == 1);
    std::cout << Label;
    _getch();
    return 0;
}
void Test()
{
    Label++;
    while (Start != Last)
    {
        a = Queue[0][Start];
        b = Queue[1][Start];
        if (array[a - 1][b] == 1) Add(a - 1, b);//++
        if (array[a + 1][b] == 1) Add(a + 1, b);
        if (array[a][b + 1] == 1) Add(a, b + 1);
        if (array[a][b - 1] == 1) Add(a, b - 1);
        Start++;
    }
}
void Find()
{
    p = 0;
    for (i = 1; i <= N && p == 0; i++)
        for (j = 1; j <= M && p == 0; j++)
            if (array[i][j] == 1)
            {
                p = 1;
                Add(i, j);
            }
}
void Add(int x, int y)
{
    Queue[0][Last] = x;
    Queue[1][Last] = y;
    array[x][y] = Label;
    Last++;
}

Строка, где //++, крашит программу, помогите с примером и задачей...
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.09.2016, 14:56
Ответы с готовыми решениями:

Расстановка кораблей (морской бой)
Доброго времени суток, при расстановке 2х палубных кораблей возникает проблема... При выборе точки...

Консольный морской бой. Расстановка кораблей
Добрый вечер, уважаемые форумчане. Хочу написать консольный морской бой. Начал с функции...

Морской бой.Обработка массива. Расстановка кораблей
Пытаюсь написать морской бой. Свою карту я подгружаю из файла. Проблема в том, что у меня не...

Морской бой - программа зацикливается на расстановке кораблей
Нужно написать курсовую(игру). Решила написать морской бой(пока что консольно). Написала программу...

18
7362 / 6284 / 2856
Регистрация: 14.04.2014
Сообщений: 27,223
27.09.2016, 15:24 2
Почему строк только 8 задано? Так и задумано?
0
125 / 117 / 67
Регистрация: 07.11.2014
Сообщений: 788
27.09.2016, 15:27  [ТС] 3
nmcf, можно вообще любое кол-во, но не вместится на 4х4 и т.д., а 2 столбца и 2 строки дополнительных - это для того, чтобы не выйти за пределы матрицы.
0
7362 / 6284 / 2856
Регистрация: 14.04.2014
Сообщений: 27,223
27.09.2016, 15:51 4
У тебя 10 строк указано в размере (N + 2), а задаёшь только 8. Это нормально?
0
125 / 117 / 67
Регистрация: 07.11.2014
Сообщений: 788
27.09.2016, 15:57  [ТС] 5
nmcf, так при проверке смежных клеток через Test чтобы не выйти за пределы матрицы же) Нормально
0
7362 / 6284 / 2856
Регистрация: 14.04.2014
Сообщений: 27,223
27.09.2016, 15:59 6
Но столбцов-то ты 10 инициализируешь нулями/единицами, а строк 8. Не понятно.
0
125 / 117 / 67
Регистрация: 07.11.2014
Сообщений: 788
27.09.2016, 16:06  [ТС] 7
nmcf, аа, щас исправлю, спасибо. Теперь код такой:
Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <conio.h>
const int N = 8, M = 8;
void Add(int x, int y);
void Test();
void Find();
int Label,p,i,j,a,b;
int Start, Last;
int array[N+2][M+2] = {
    {0,0,0,0,0,0,0,0,0,0},
    {0,1,0,0,1,1,1,0,1,0},
    {0,1,0,1,0,0,0,1,0,0},
    {0,1,0,0,0,1,0,0,0,0},
    {0,1,0,1,1,0,1,1,1,0},
    {0,0,0,0,0,0,0,0,0,0},
    {0,1,1,0,1,1,0,1,1,0},
    {0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0}};
int Queue[2][N*M];
int main() {
    Start = 0;
    Last = 0;
    Label = 0;
    p = 1;
    do
    {
        Find();
        if (p == 1) Test();
    } while (p == 1);
    std::cout << Label;
    _getch();
    return 0;
}
void Test()
{
    Label++;
    while (Start != Last)
    {
        a = Queue[0][Start];
        b = Queue[1][Start];
        if (array[a - 1][b] == 1) Add(a - 1, b);//++
        if (array[a + 1][b] == 1) Add(a + 1, b);
        if (array[a][b + 1] == 1) Add(a, b + 1);
        if (array[a][b - 1] == 1) Add(a, b - 1);
        Start++;
    }
}
void Find()
{
    p = 0;
    for (i = 1; i <= N && p == 0; i++)
        for (j = 1; j <= M && p == 0; j++)
            if (array[i][j] == 1)
            {
                p = 1;
                Add(i, j);
            }
}
void Add(int x, int y)
{
    Queue[0][Last] = x;
    Queue[1][Last] = y;
    array[x][y] = Label;
    Last++;
}

Проблема не решена, все равно крашится
0
7362 / 6284 / 2856
Регистрация: 14.04.2014
Сообщений: 27,223
27.09.2016, 16:46 8
Отладчиком смотрел? Индексы правильные?
0
125 / 117 / 67
Регистрация: 07.11.2014
Сообщений: 788
27.09.2016, 16:58  [ТС] 9
nmcf, не смотрел, индексы вроде правильные, именно та строка(42) рушит программу
А как посмотреть? VS есть, после ошибки прерываю, дальше что?)

Добавлено через 1 минуту
nmcf, желтая стрелка вот на эту строку показывает:
C++
1
Queue[1][Last] = y;
0
7362 / 6284 / 2856
Регистрация: 14.04.2014
Сообщений: 27,223
27.09.2016, 18:57 10
Текст ошибки какой?
В пошаговом режиме смотри за индексами.
0
125 / 117 / 67
Регистрация: 07.11.2014
Сообщений: 788
29.09.2016, 16:59  [ТС] 11
nmcf, ошибка не при компилировании, а при запуске программы. Такое ощущение, будто делаю что-то невозможное(делю на ноль/выхожу за пределы массива/бесконечный цикл)
Но такого не замечаю, да и условие примитивное...
0
7362 / 6284 / 2856
Регистрация: 14.04.2014
Сообщений: 27,223
29.09.2016, 18:21 12
Ну вот отладчиком и смотри в пошаговом режиме.
0
125 / 117 / 67
Регистрация: 07.11.2014
Сообщений: 788
29.09.2016, 20:49  [ТС] 13
nmcf, Ну не умею я((
0
Эксперт С++
3220 / 1747 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
30.09.2016, 13:11 14
Лучший ответ Сообщение было отмечено Aymurat как решение

Решение

Цитата Сообщение от Aymurat Посмотреть сообщение
задача взята из книги Динман Максима C++ Освой на примерах.
Там есть первый пример, который очень схож с этой задачей, код не выполняется:
Кошмар! Программа спроектирована просто ужасно, в стиле программ на древнем Бейсике. Иногда поражаешься, какие дебилы пишут книги с поучениями.
Во-первых, непонятно при чем тут С++. Какие-то сплошь глобальные переменные с дурацкими буковками вместо имен.
Слепые, ничего не объясняющие имена функций. Ну и автор книги таки алфавита не знает! У него N предшествует M!
Завидую мужеству автора темы, который может в этом ковыряться. Кроме острого желания поблевать эта программа ничего не вызывает, и единственное, что с ней можно сделать, - это показывать детям, чтобы, не дай Бог, никогда такого не писали.


Мой вариант:
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
//Есть матрица NxM, где расставлены корабли. Корабли не стоят на краю матрицы,
//кол-во 4-х клеточных кораблей - 1, 3-х клет. - 2, 2-х клеточных - 3, 1-х - 4
//Нужно проверить правильно ли расстановлены и ответить YES,NO;
//Матрица заполняется 0 и 1, где 1 это клетка корабля.
//Корабли не должны соприкасаться друг с другом и должны быть все корабли
//(не меньше, не больше)
///////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <complex>
#include <iostream>
#include <set>
#include <utility>
#include <vector>
///////////////////////////////////////////////////////////////////////////////
const   int     M   =   10;
const   int     N   =   10;
///////////////////////////////////////////////////////////////////////////////
typedef int                             (& T_matr_ref)[M][N];
typedef int                             T_coord;
typedef std::complex    < T_coord   >   T_cell;
typedef std::vector     < int       >   T_counters;
typedef std::set        < T_cell    >   T_cells;
typedef T_cells                         T_ship;
///////////////////////////////////////////////////////////////////////////////
namespace std
{
    bool    operator<
        (
            T_cell  const   &   L,
            T_cell  const   &   R
        )
    {
        return      std::make_pair( L.real(),   L.imag()    )
                <   std::make_pair( R.real(),   R.imag()    );
    }
}
///////////////////////////////////////////////////////////////////////////////
bool    cells_are_neighbors
    (
        T_cell  A,
        T_cell  B
    )
{
    return          std::abs    (
                                    A.real()    -   B.real()
                                )
 
                +   std::abs    (
                                    A.imag()    -   B.imag()
                                )
 
            ==  1;
}
///////////////////////////////////////////////////////////////////////////////
bool    cell_on_edge( T_cell    cell )
{
    return      cell.real()   ==  0
            ||  cell.real()   ==  M - 1
 
            ||  cell.imag()   ==  0
            ||  cell.imag()   ==  N - 1;
}
///////////////////////////////////////////////////////////////////////////////
bool    ship_is_correct( T_ship     const   &   ship )
{
    int     i_min   =   M;
    int     j_min   =   N;
 
    int     i_max   =   -1;
    int     j_max   =   -1;
 
    for( auto   cell    :   ship )
    {
        auto    i   =   cell.real();
        auto    j   =   cell.imag();
 
        if  (
                cell_on_edge( cell )
            )
        {
            return  false;
        }
 
        if( i < i_min )     {   i_min    =   i; }
        if( i > i_max )     {   i_max    =   i; }
 
        if( j < j_min )     {   j_min    =   j; }
        if( j > j_max )     {   j_max    =   j; }
    }//for
 
    auto    delta_i     =   i_max  -   i_min;
    auto    delta_j     =   j_max  -   j_min;
 
    return      delta_i     *   delta_j     ==  0
 
            &&  ++delta_i   *   ++delta_j   ==  int (
                                                        ship.size()
                                                    );
}
///////////////////////////////////////////////////////////////////////////////
void    search_ship
    (
        T_cell      &   cell,
        T_matr_ref      matr,
        T_ship      &   ship,
        T_cells     &   marked_cells
    )
{
    marked_cells    .emplace    ( cell );
    ship            .emplace    ( cell );
 
    int     i   =   cell.real();
    int     j   =   cell.imag();
 
    for (
            int
            ii  =   std::max( i - 1,    0       );
            ii  <=  std::min( i + 1,    M - 1   );
            ++ii
        )
    {
        for (
                int
                jj  =   std::max( j - 1,    0       );
                jj  <=  std::min( j + 1,    N - 1   );
                ++jj
            )
        {
            T_cell  cell_cur(ii, jj);
 
            if  (
                        matr[ii][jj]
                    &&  !marked_cells.count( cell_cur           )
                    &&  cells_are_neighbors( cell_cur,  cell    )
                )
            {
                search_ship (
                                cell_cur,
                                matr,
                                ship,
                                marked_cells
                            );
            }
        }//for
    }//for
}
///////////////////////////////////////////////////////////////////////////////
bool    ships_matr_is_correct   ( T_matr_ref    matr )
{
    T_cells     marked_cells;
    T_counters  counters    {0,4,3,2,1};
 
    for( size_t  i{}; i < M; ++i )
    {
        for( size_t  j{}; j < N; ++j )
        {
            if  (
                    matr[i][j]  ==  0
                )
            {
                continue;
            }
 
            T_cell  cell_cur(i, j);
 
            if  (
                    marked_cells.count( cell_cur )
                )
            {
                continue;
            }
 
            T_ship  ship;
 
            search_ship
                (
                    cell_cur,
                    matr,
                    ship,
                    marked_cells
                );
 
            if  (
                    ship_is_correct( ship )
                )
            {
                --counters[ ship.size() ];
            }
            else
            {
                return  false;
            }
        }//for
    }//for
 
    return  counters    ==  T_counters  (
                                            counters.size()
                                        );
}
///////////////////////////////////////////////////////////////////////////////
int     main()
{
    int     matr[M][N]  =   {
                                {0,0,0,0,0,0,0,0,0,0},
                                {0,0,0,0,1,1,1,0,1,0},
                                {0,0,0,1,0,0,0,0,0,0},
 
                                {0,0,0,0,0,1,0,0,0,0},
                                {0,0,0,1,1,0,1,1,1,0},
                                {0,0,0,0,0,0,0,0,0,0},
 
                                {0,1,1,0,1,1,0,0,1,0},
                                {0,0,0,0,0,0,0,0,0,0},
                                {0,0,0,0,0,1,1,1,1,0},
 
                                {0,0,0,0,0,0,0,0,0,0}
                            };
 
    std::cout   <<  (
                        ships_matr_is_correct( matr )
                            ?   "YES"
                            :   "NO"
                    )
 
                <<  std::endl;
}
2
7362 / 6284 / 2856
Регистрация: 14.04.2014
Сообщений: 27,223
30.09.2016, 14:17 15
Что там уметь? Точку останова перед этим циклом сделай, запусти, и программа там остановится. Дальше пошагово - в меню посмотри какие клавиши нажимать.
1
125 / 117 / 67
Регистрация: 07.11.2014
Сообщений: 788
01.10.2016, 11:12  [ТС] 16
Mr.X, спасибо, программа работает, но много непонятных моментов, можете прокомментировать код?
0
Эксперт С++
3220 / 1747 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
01.10.2016, 16:19 17
Цитата Сообщение от Aymurat Посмотреть сообщение
Mr.X, спасибо, программа работает, но много непонятных моментов, можете прокомментировать код?
Да он вроде бы самодокументируемый. А что непонятно?
Кстати, там можно обойтись без комплексных чисел:
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
//Есть матрица NxM, где расставлены корабли. Корабли не стоят на краю матрицы,
//кол-во 4-х клеточных кораблей - 1, 3-х клет. - 2, 2-х клеточных - 3, 1-х - 4
//Нужно проверить правильно ли расстановлены и ответить YES,NO;
//Матрица заполняется 0 и 1, где 1 это клетка корабля.
//Корабли не должны соприкасаться друг с другом и должны быть все корабли
//(не меньше, не больше)
///////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <iostream>
#include <set>
#include <utility>
#include <vector>
///////////////////////////////////////////////////////////////////////////////
const   int     M   =   10;
const   int     N   =   10;
///////////////////////////////////////////////////////////////////////////////
typedef int                                     (&  T_matr_ref)[M][N];
typedef int                                     T_coord;
typedef std::pair       < T_coord,  T_coord >   T_cell;
typedef std::vector     < int       >           T_counters;
typedef std::set        < T_cell    >           T_cells;
typedef T_cells                                 T_ship;
///////////////////////////////////////////////////////////////////////////////
bool    cells_are_neighbors
    (
        T_cell  A,
        T_cell  B
    )
{
    return          std::abs( A.first   -   B.first     )
                +   std::abs( A.second  -   B.second    )
            ==  1;
}
///////////////////////////////////////////////////////////////////////////////
bool    cell_on_edge( T_cell    cell )
{
    return      cell.first      ==  0
            ||  cell.first      ==  M - 1
 
            ||  cell.second     ==  0
            ||  cell.second     ==  N - 1;
}
///////////////////////////////////////////////////////////////////////////////
bool    ship_is_correct( T_ship     const   &   ship )
{
    int     i_min   =   M;
    int     j_min   =   N;
 
    int     i_max   =   -1;
    int     j_max   =   -1;
 
    for( auto   cell    :   ship )
    {
        auto    i   =   cell.first;
        auto    j   =   cell.second;
 
        if  (
                cell_on_edge( cell )
            )
        {
            return  false;
        }
 
        if( i < i_min )     {   i_min    =   i; }
        if( i > i_max )     {   i_max    =   i; }
 
        if( j < j_min )     {   j_min    =   j; }
        if( j > j_max )     {   j_max    =   j; }
    }//for
 
    auto    delta_i     =   i_max  -   i_min;
    auto    delta_j     =   j_max  -   j_min;
 
    return      delta_i     *   delta_j     ==  0
 
            &&  ++delta_i   *   ++delta_j   ==  int (
                                                        ship.size()
                                                    );
}
///////////////////////////////////////////////////////////////////////////////
void    search_ship
    (
        T_cell      &   cell,
        T_matr_ref      matr,
        T_ship      &   ship,
        T_cells     &   marked_cells
    )
{
    marked_cells    .emplace    ( cell );
    ship            .emplace    ( cell );
 
    int     i   =   cell.first;
    int     j   =   cell.second;
 
    for (
            int
            ii  =   std::max( i - 1,    0       );
            ii  <=  std::min( i + 1,    M - 1   );
            ++ii
        )
    {
        for (
                int
                jj  =   std::max( j - 1,    0       );
                jj  <=  std::min( j + 1,    N - 1   );
                ++jj
            )
        {
            T_cell  cell_cur(ii, jj);
 
            if  (
                        matr[ii][jj]
                    &&  !marked_cells.count( cell_cur           )
                    &&  cells_are_neighbors( cell_cur,  cell    )
                )
            {
                search_ship (
                                cell_cur,
                                matr,
                                ship,
                                marked_cells
                            );
            }
        }//for
    }//for
}
///////////////////////////////////////////////////////////////////////////////
bool    ships_matr_is_correct   ( T_matr_ref    matr )
{
    T_cells     marked_cells;
    T_counters  counters    {0,4,3,2,1};
 
    for( size_t  i{}; i < M; ++i )
    {
        for( size_t  j{}; j < N; ++j )
        {
            T_cell  cell_cur(i, j);
 
            if  (
                        matr[i][j]  ==  0
                    ||  marked_cells.count( cell_cur )
                )
            {
                continue;
            }
 
            T_ship  ship;
 
            search_ship
                (
                    cell_cur,
                    matr,
                    ship,
                    marked_cells
                );
 
            if  (
                    ship_is_correct( ship )
                )
            {
                --counters[ ship.size() ];
            }
            else
            {
                return  false;
            }
        }//for
    }//for
 
    return  counters    ==  T_counters  (
                                            counters.size()
                                        );
}
///////////////////////////////////////////////////////////////////////////////
int     main()
{
    int     matr[M][N]  =   {
                                {0,0,0,0,0,0,0,0,0,0},
                                {0,0,0,0,1,1,1,0,1,0},
                                {0,0,0,1,0,0,0,0,0,0},
 
                                {0,0,0,0,0,1,0,0,0,0},
                                {0,0,0,1,1,0,1,1,1,0},
                                {0,0,0,0,0,0,0,0,0,0},
 
                                {0,1,1,0,1,1,0,0,1,0},
                                {0,0,0,0,0,0,0,0,0,0},
                                {0,0,0,0,0,1,1,1,1,0},
 
                                {0,0,0,0,0,0,0,0,0,0}
                            };
 
    std::cout   <<  (
                        ships_matr_is_correct( matr )
                            ?   "YES"
                            :   "NO"
                    )
 
                <<  std::endl;
}
0
125 / 117 / 67
Регистрация: 07.11.2014
Сообщений: 788
01.10.2016, 16:46  [ТС] 18
Mr.X, я вообще не работал с контейнерами, векторами и комплексными числами. Хотя бы на словах объясните алгоритм? Да и из-за typedef путаюсь где что, новичку сложно разобраться в таком коде... Да и стиль у вас какой-то странный, везде пробелы) Вот в такую форму привел я:
Кликните здесь для просмотра всего текста
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
#include <algorithm>
#include <complex>
#include <iostream>
#include <set>
#include <utility>
#include <conio.h>
#include <vector>
const int M = 10;
const int N = 10;
typedef int(&T_matr_ref)[M][N];
typedef int T_coord;
typedef std::complex<T_coord> T_cell;
typedef std::vector<int> T_counters;
typedef std::set<T_cell> T_cells;
typedef T_cells T_ship;
namespace std
{
    bool    operator< (T_cell  const   &   L, T_cell  const  &  R)
    {
        return    std::make_pair(L.real(), L.imag())< std::make_pair(R.real(), R.imag());
    }
}
bool    cells_are_neighbors (T_cell  A, T_cell  B)
{
    return  std::abs(A.real() - B.real()) + std::abs(A.imag() - B.imag()) == 1;
}
bool    cell_on_edge(T_cell    cell)
{
    return   cell.real() == 0 || cell.real() == M - 1 || cell.imag() == 0   || cell.imag() == N - 1;
}
bool    ship_is_correct(T_ship     const   &   ship)
{
    int     i_min = M;
    int     j_min = N;
 
    int     i_max = -1;
    int     j_max = -1;
 
    for (auto cell : ship)
    {
        auto    i = cell.real();
        auto    j = cell.imag();
 
        if (cell_on_edge(cell)) return  false;
 
        if (i < i_min) { i_min = i; }
        if (i > i_max) { i_max = i; }
 
        if (j < j_min) { j_min = j; }
        if (j > j_max) { j_max = j; }
    }//for
 
    auto    delta_i = i_max - i_min;
    auto    delta_j = j_max - j_min;
 
    return   delta_i*delta_j==0 && ++delta_i*++delta_j == int(ship.size());
}
void    search_ship(T_cell & cell,T_matr_ref matr,T_ship  & ship,T_cells & marked_cells)
{
    marked_cells.emplace(cell);
    ship.emplace(cell);
 
    int     i = cell.real();
    int     j = cell.imag();
 
    for (int ii = std::max(i - 1, 0);   ii <= std::min(i + 1, M - 1); ++ii)
    {
        for (int jj = std::max(j - 1, 0);   jj <= std::min(j + 1, N - 1);   ++jj)
        {
            T_cell  cell_cur(ii, jj);
            if (matr[ii][jj] && !marked_cells.count(cell_cur) && cells_are_neighbors(cell_cur, cell))
                search_ship(cell_cur,matr,ship, marked_cells);
        }//for
    }//for
}
bool    ships_matr_is_correct(T_matr_ref    matr)
{
    T_cells     marked_cells;
    T_counters  counters{ 0,4,3,2,1 };
 
    for (size_t i{}; i < M; ++i)
    {
        for (size_t j{}; j < N; ++j)
        {
            if (matr[i][j] == 0) continue;
            T_cell  cell_cur(i, j);
            if (marked_cells.count(cell_cur))continue;
            T_ship  ship;
            search_ship (cell_cur,matr,ship,marked_cells);
            if (ship_is_correct(ship))  --counters[ship.size()];
            else
            return  false;
        }//for
    }//for
    return  counters == T_counters( counters.size() );
}
int main()
{
    int matr[M][N] = {
        { 0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,1,1,1,0,1,0 },
        { 0,0,0,1,0,0,0,0,0,0 },
        { 0,0,0,0,0,1,0,0,0,0 },
        { 0,0,0,1,1,0,1,1,1,0 },
        { 0,0,0,0,0,0,0,0,0,0 },
        { 0,1,1,0,1,1,0,0,1,0 },
        { 0,0,0,0,0,0,0,0,0,0 },
        { 0,0,0,0,0,1,1,1,1,0 },
        { 0,0,0,0,0,0,0,0,0,0 }
    };
    std::cout << (ships_matr_is_correct(matr)? "YES": "NO") << std::endl; 
    _getch();
}

Перегрузка оператора < , для чего она?
0
Эксперт С++
3220 / 1747 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
01.10.2016, 18:29 19
Цитата Сообщение от Aymurat Посмотреть сообщение
Вот в такую форму привел я
Вам правда в такой записи читать легче? Я в ней ни бельмеса не вижу!
Цитата Сообщение от Aymurat Посмотреть сообщение
я вообще не работал с контейнерами, векторами и комплексными числами.
Ну, вы же задачи решаете чтобы язык освоить? Тут как раз удобный случай, чтобы с ними ознакомиться, тем более, что в них ничего сложного нет. Как только освоите незнакомые слова, так все сразу ясно станет.
Цитата Сообщение от Aymurat Посмотреть сообщение
Перегрузка оператора < , для чего она?
Ну, комплексные числа не имеют встроенного оператора <. В моем втором варианте они не используются.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.10.2016, 18:29
Помогаю со студенческими работами здесь

Морской бой. Ф-ция автоматической рассатновки кораблей.
Добрый день, ув. форумчане! Есть задание написать консольный морской бой. Есть задача расстановки...

Морской бой: расставляется кораблей больше, чем положено
Здравствуйте! Пишу игру &quot;Морской бой&quot; в консоли, и попалась одна неприятная ситуация. Есть функция...

Создать класс, реализующий хранилище кораблей для игрока в «Морской бой»
Всем привет. Это задача по теме контейнерные классы. Не бейте только за глупый вопрос. Но в данной...

Случайное распределение кораблей по полю в игре "морской бой"
Привет всем кто читал мой предыдущий пост про векторы в морском боем, в той же фунции появилась...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru