Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
0 / 0 / 0
Регистрация: 11.08.2020
Сообщений: 23

Олимпиадная задача на bfs

11.08.2020, 01:04. Показов 4767. Ответов 46
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Была задана вот такая задача:

Всем известна увлекательная игра «Морской бой». Сейчас играть в морской бой можно не только с соседом по парте, но и с компьютером. Игра c компьютером ведется на прямоугольном поле произвольных размеров N×M, где N - количество строк, M - количество столбцов. Приближается чемпионат Мира по морскому бою. Планируется вести его трансляцию в режиме реального времени: демонстрировать карту с кораблями и выводить статистику: количество целых, подбитых и уничтоженных кораблей, находящихся на поле. Требуется написать программу для подсчета статистики.

Корабль на поле — это связанная фигура, стоящая из одной или нескольких рядом лежащих клеток, имеющих общую сторону. Корабли могут быть абсолютно любых форм и размеров!

Входные данные
Первая строка входного файла INPUT.TXT содержит два целых числа N и M (1≤ N,M ≤ 103), разделённых пробелами - размеры игрового поля. Далее идут N строк по M символов - описание игрового поля.

Английская буква 'X' обозначает подбитую клетку корабля, 'S' - не подбитую клетку корабля, '-' – свободное водное пространство.
Выходные данные
В выходной файл OUTPUT.TXT выведите через пробел три числа:

количество целых кораблей
количество подбитых кораблей
количество уничтоженных кораблей
Пример №1
C++
1
2
3
4
5
6
7
INPUT.TXT
3 8
---SSS--
XX--S-X-
X-S---S-
OUTPUT.TXT
2 1 1
Начал решать, тесты из примера все прошли. Но в дальнейших проверках встречается превышение выделенной памяти из-за чего программа не засчитывается. Кто может подсказать, как ускорить программу? Также не откажусь от куска алгоритма, который поможет это решить (готовое решение также приветствуется, буду разбираться). Вот мой код:

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
#include <iostream>
#include <vector>
using namespace std;
   
int arr[1001][1001];
int n, m, k = 0;
 
vector<vector<int> > types;
 
bool check(vector<int> vc){
    for(int i : vc) if(i != vc[0]) return false;
    return true;
}
void G(int i, int j){
    if(0 <= i && i < n && 0 <= j && j < m){
        if(arr[i][j]){
            types[k].push_back(arr[i][j]);
            arr[i][j] = 0;
            G(i + 1, j);
            G(i - 1, j);
            G(i, j + 1);
            G(i, j - 1);
        }
    }
}
int main() {
   char x;
   cin >> n >> m;
   types.resize(n * m);
   for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++){
            cin >> x;
            if(x == '-') arr[i][j] = 0;
            else if(x == 'S') arr[i][j] = 1;
            else if(x == 'X') arr[i][j] = 2;
        }
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++){
            if(arr[i][j]) {
                G(i, j);
                k++;
            }
        }
    int ans[] = {0, 0, 0};
    for(int i = 0; i < k; i++){
       if(check(types[i])){
           if(types[i][0] == 1) ans[0]++;
           else ans[2]++;
       } else ans[1]++;
    }
    for(int i : ans) cout << i << " ";
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.08.2020, 01:04
Ответы с готовыми решениями:

Олимпиадная задача по программированию. PascalABC.NET. Задача L. Переключение между окнами
Когда пользователь работает в операционной системе Winux, у него часто запущено несколько приложений. Каждое из приложений работает в...

Считалка. Олимпиадная задача по программированию
Ирочка попросила маму придумать новую считалочку. Мама тут же ей &quot;выдала&quot;. Пусть в кругу N человек. Это число N будем изменять...

Олимпиадная задача
Кот Василий узнал, что у соседа Димы, проживающего от него через какое-то количество заборов завелись мыши. Так как в своём хозяйстве всех...

46
0 / 0 / 0
Регистрация: 11.08.2020
Сообщений: 23
11.08.2020, 15:16  [ТС]
Студворк — интернет-сервис помощи студентам
Именно так и сделал, сравнение везде стояло напрямую по символам
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2020, 15:19
Цитата Сообщение от programmist- Посмотреть сообщение
Именно так и сделал, сравнение везде стояло напрямую по символам
И зачем убрал?
0
0 / 0 / 0
Регистрация: 11.08.2020
Сообщений: 23
11.08.2020, 15:20  [ТС]
Не убирал. После того, как вы предложили сменить int на char, я и сменил, но потом написал, что и это не помогло, тк памяти стало заниматься еще больше, чем с int
0
фрилансер
 Аватар для Алексей1153
6494 / 5722 / 1133
Регистрация: 11.10.2019
Сообщений: 15,282
11.08.2020, 15:22
Цитата Сообщение от programmist- Посмотреть сообщение
Английская буква 'X' обозначает подбитую клетку корабля, 'S' - не подбитую клетку корабля, '-' – свободное водное пространство.
по идее, можно 2 бита на клетку сделать. Расход памяти сократится, но время выполнения может подрасти

Добавлено через 59 секунд
и, соответственно, вместо vector<vector<int> > types сделать vector<uint8_t> нужной длины
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2020, 15:52
Цитата Сообщение от programmist- Посмотреть сообщение
Не убирал. После того, как вы предложили сменить int на char, я и сменил, но потом написал, что и это не помогло, тк памяти стало заниматься еще больше, чем с int
функция G у тебя должна возвращать состояние корабля - живой/ранен/убит. Для этого достаточно двух бит. Что-то типа
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
uint8_t G(int i, int j)
{
    if (i < 0 || i == n || j < 0 || j == m)
        return 0;
 
    const char x = arr[i * n + j];
    if (x == '-')
        return 0;
 
    const uint8_t res = x == 'X'? 0x1: 0x2;
    return res
        | G(i + 1, j)
        | G(i - 1, j)
        | G(i, j + 1)
        | G(i, j - 1);
}
Добавлено через 4 минуты
C++
1
2
3
4
int ans[4] = {0, 0, 0, 0};
for(int i = 0; i < n; i++)
    for(int j = 0; j < m; j++)
        ++ans[G(i, j)];
Добавлено через 13 минут
Сбрасывать ещё надо просмотренные клетки
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
uint8_t G(int i, int j)
{
    if (i < 0 || i == n || j < 0 || j == n)
        return 0;
 
    char &x = arr[i * n + j];
    if (x == '-')
        return 0;
 
    uint8_t res = x == 'X'? 0x1: 0x2;
    x = '-';
    return res
        | G(i + 1, j)
        | G(i - 1, j)
        | G(i, j + 1)
        | G(i, j - 1);
}
0
0 / 0 / 0
Регистрация: 11.08.2020
Сообщений: 23
11.08.2020, 16:05  [ТС]
А почему для ans вы выделили 4 ячейки?
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2020, 16:11
Цитата Сообщение от programmist- Посмотреть сообщение
А почему для ans вы выделили 4 ячейки?
Чтоб на ноль не проверять.
1 - убит, 2 - живой, 3 - ранен

Добавлено через 49 секунд
0 - количество пустых ячеек
0
0 / 0 / 0
Регистрация: 11.08.2020
Сообщений: 23
11.08.2020, 16:25  [ТС]
Вывод у программы по вашему алгоритму довольно странный - 19 3 2 0, данные по кораблям совсем другие
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2020, 16:27
Цитата Сообщение от programmist- Посмотреть сообщение
Вывод у программы по вашему алгоритму довольно странный - 19 3 2 0, данные по кораблям совсем другие
А должны быть какие?
0
0 / 0 / 0
Регистрация: 11.08.2020
Сообщений: 23
11.08.2020, 16:32  [ТС]
2 целых корабля
1 подбитый
1 уничтоженный
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2020, 16:41
Цитата Сообщение от programmist- Посмотреть сообщение
2 целых корабля
1 подбитый
1 уничтоженный
Ошибся в размерностях массива

Добавлено через 2 минуты
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
int n = 3, m = 8;
char arr[] =
    "---SSS--"
    "XX--S-X-"
    "X-S---S-";
 
uint8_t G(int i, int j)
{
    if (i < 0 || i == n || j < 0 || j == m)
        return 0;
 
    char &x = arr[i * m + j];
    if (x == '-')
        return 0;
 
    uint8_t res = x == 'X'? 0x1: 0x2;
    x = '-';
    return res
        | G(i + 1, j)
        | G(i - 1, j)
        | G(i, j + 1)
        | G(i, j - 1);
}
 
int main()
{
    int ans[4] = {0, 0, 0, 0};
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
            ++ans[G(i, j)];
 
    std::cout 
        << ans[2] << " "
        << ans[3] << " "
        << ans[1] << std::endl;
    return 0;
}
0
0 / 0 / 0
Регистрация: 11.08.2020
Сообщений: 23
11.08.2020, 18:16  [ТС]
Теперь TL ..
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2020, 18:18
Цитата Сообщение от programmist- Посмотреть сообщение
Теперь TL ..
В смысле? Покажи, как сделал
0
0 / 0 / 0
Регистрация: 11.08.2020
Сообщений: 23
11.08.2020, 18:19  [ТС]
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
#include <iostream>
 
using namespace std;
 
int n, m;
char arr[1001];
 
uint8_t G(int i, int j)
{
    if (i < 0 || i == n || j < 0 || j == m)
        return 0;
 
    char &x = arr[i * m + j];
    if (x == '-')
        return 0;
 
    uint8_t res = x == 'X'? 0x1: 0x2;
    x = '-';
    return res
        | G(i + 1, j)
        | G(i - 1, j)
        | G(i, j + 1)
        | G(i, j - 1);
}
 
int main()
{
    cin >> n >> m;
    for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) cin >> arr[i * m + j];
    int ans[4] = {0, 0, 0, 0};
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
            ans[G(i, j)]++;
 
    cout << ans[2] << " " << ans[3] << " " << ans[1];
}
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
11.08.2020, 21:57
Цитата Сообщение от programmist- Посмотреть сообщение
char arr[1001];
А зачем ты у брал динамическое выделение памяти? У тебя там по условию поле может быть 103 x 103, это явно больше, чем 1001

Добавлено через 53 секунды
C++
1
2
3
4
5
int main()
{
    cin >> n >> m;
arr = new char[m * n];
    for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) cin >> arr[i * m + j];
0
0 / 0 / 0
Регистрация: 11.08.2020
Сообщений: 23
11.08.2020, 22:47  [ТС]
И снова превышение памяти на том же тесте, что и бы в самый первый раз
0
фрилансер
 Аватар для Алексей1153
6494 / 5722 / 1133
Регистрация: 11.10.2019
Сообщений: 15,282
11.08.2020, 23:02
programmist-, можно попробовать однострочное сканирование доски (сверху вниз, например). Алгоритм будет сложнее, но памяти потребуется немного. Скорость работы предсказать не берусь
0
0 / 0 / 0
Регистрация: 11.08.2020
Сообщений: 23
11.08.2020, 23:03  [ТС]
Буду пробовать
0
фрилансер
 Аватар для Алексей1153
6494 / 5722 / 1133
Регистрация: 11.10.2019
Сообщений: 15,282
12.08.2020, 03:44
programmist-, чтобы не так скучно было пробовать, накидал свой вариант построчного сканирования.

Внимание! В этом варианте есть ограничения, введённые для отладки. Они сожрут всю память и время, если сейчас подать большие поля.

Класс s_ship_debug_info и мапа td_ships_debug_list - отладочные. показано, как накопить нужную информацию + вывод в консоль

от "дебажности", само собой, тебе предстоит избавиться, заменив на подсчёт статистики

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
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
/*тоже C++17 , если что*/
#include <sstream>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <vector>
#include <string>
 
constexpr char water_char='-';
 
//тест 1
/*
static const std::string INPUT_TXT=
        "3 3\n"
        "X-X\n"
        "XXX\n"
        "X-X\n"
        ;
*/
 
//тест 2
/*
static const std::string INPUT_TXT=
        "3 8\n"
        "---SSS--\n"
        "XX--S-X-\n"
        "X-S---S-\n"
        ;
*/
 
//тест 3
static const std::string INPUT_TXT=
        "8 8\n"
        "---SSS--\n"
        "XX--S-X-\n"
        "X-S---S-\n"
        "X-------\n"
        "X-XXXXS-\n"
        "X-S---S-\n"
        "X-SXXXS-\n"
        "X-------\n"
        ;
 
 
using td_coord=uint32_t;
using td_ship_index=uint32_t;
constexpr td_ship_index ship_index_null=0;
 
struct s_ship_debug_info
{
    //координаты корабля и символ
    std::map<std::pair<td_coord/*x*/,td_coord/*y*/>,char> cells;
 
    void Append(const s_ship_debug_info& info)
    {
        if(this==&info)return;
        for(const auto& i:info.cells)
        {
            cells.emplace(i);
        }
    }
 
    void Print(const td_ship_index inx,const td_ship_index hig,const td_ship_index wid)const
    {
        std::cout<<"ship #"<<inx<<" = ";
        for(const auto& cell:cells)
        {
            std::cout<<"("<<cell.first.first<<", "<<cell.first.second<<") ";
        }
        std::cout<<'\n';
        //std::cout<<"map"<<'\n';
 
        if(cells.size())
        {
            auto [x_min,y_min]=cells.begin()->first; {}//скобки в конце поставлены для лечения моего парсера IDE,
            auto [x_max,y_max]=cells.begin()->first; {}//иначе эта строка вправо выдвигается. Если у тебя норм, то убери
 
            //ищем границы
            for(const auto& cell:cells)
            {
                x_min=std::min(x_min,cell.first.first);
                y_min=std::min(y_min,cell.first.second);
                x_max=std::max(x_max,cell.first.first);
                y_max=std::max(y_max,cell.first.second);
            }
 
            //выводим полотно
 
            //пустые линии до
            for(td_coord y=0; y<y_min; y++)
            {
                for(td_coord x=0; x<wid; x++)std::cout<<water_char;
                std::cout<<'\n';
            }
 
            //линии корабля
            for(td_coord y=y_min; y<=y_max; y++)
            {
                //пустые колонки до
                for(td_coord x=0; x<x_min; x++)std::cout<<water_char;
 
                //колонки корабля
                for(td_coord x=x_min; x<=x_max; x++)
                {
                    auto it=cells.find({x,y});
                    if(it==cells.end())
                    {
                        std::cout<<water_char;
                    }
                    else
                    {
                        std::cout<<it->second;
                    }
                }
 
                //пустые колонки после
                for(td_coord x=x_max+1; x<wid; x++)std::cout<<water_char;
                std::cout<<'\n';
            }
 
            //пустые линии после
            for(td_coord y=y_max+1; y<hig; y++)
            {
                for(td_coord x=0; x<wid; x++)std::cout<<water_char;
                std::cout<<'\n';
            }
        }
    }
};
 
int main(/*int argc, char *argv[]*/)
{
    std::istringstream ss(INPUT_TXT);
 
    auto [hig,wid]=[&ss]()
    {
        td_coord hig=0;
        td_coord wid=0;
 
        std::string hig_wid;
        std::getline(ss,hig_wid);
 
        std::istringstream hw(hig_wid);
        hw>>hig;
        hw>>wid;
 
        return std::make_pair(hig,wid);
    }();
 
    using td_ships_debug_list=std::map<td_ship_index,s_ship_debug_info>;
 
    td_ships_debug_list ships_debug_list;
 
    std::vector<td_ship_index> prev_line_scanning;
    std::vector<td_ship_index> curr_line_scanning;
 
    auto ship_index_generator=[]
    {
        static td_ship_index index=ship_index_null;
        return ++index;
    };
 
    std::string scan_line;
    uint32_t file_line_index=0;
    td_coord current_y=0;
    while(std::getline(ss,scan_line))
    {
        file_line_index++;
        if(scan_line.size()!=wid)
        {
            std::cout<<"line "<<file_line_index<<": size is not equal width "<<wid<<'\n';
            return 0;
        }
 
        curr_line_scanning.clear();
        curr_line_scanning.resize(scan_line.size(),ship_index_null);
 
        //ищем недопустимые символы
        if(scan_line.end()!=std::find_if(scan_line.begin(),scan_line.end(),[](auto& c){return c!=water_char && c!='S' && c!='X';}))
        {
            std::cout<<"line "<<file_line_index<<": wrong letters found "<<wid<<'\n';
            return 0;
        }
 
        //бежим по строке и нумеруем найденные корабли
 
        //индекс текущего в линии корабля
        std::pair<td_ship_index,bool> current_ship_index{{},false};
 
        //текущая координата x
        td_coord current_x=0;
 
        //если есть предыдущая линия - сливание касающихся кораблей
        //(более новый индекс заменяется более старым)
        auto MergeWithPrevLine=[&ships_debug_list,&prev_line_scanning,&curr_line_scanning,&current_ship_index,&current_x]
        {
            if(prev_line_scanning.size()==curr_line_scanning.size())
            {
                //если выше есть корабль
                const auto prev_ship_index=prev_line_scanning[current_x];
                if(prev_ship_index!=ship_index_null)
                {
                    //а индекс другой
 
                    if(prev_ship_index!=current_ship_index.first)
                    {
                        //то сливаем корабли, это один и тот же
 
                        //новый индекс заменяем на старый в обеих линиях
                        //(бежим до current_x включительно, дальше нет смысла)
                        for(uint32_t i=0; i<=current_x; i++)
                        {
                            if(curr_line_scanning[i]==current_ship_index.first)
                            {
                                curr_line_scanning[i]=prev_ship_index;
                            }
                            if(prev_line_scanning[i]==current_ship_index.first)
                            {
                                prev_line_scanning[i]=prev_ship_index;
 
                                //из мапы содержимое старого индекса тоже
                                //нужно перекинуть в новый индекс
                                {
                                    auto& info_to_move=ships_debug_list[current_ship_index.first];
                                    ships_debug_list[prev_ship_index].Append(info_to_move);
                                    ships_debug_list.erase(current_ship_index.first);
                                }
                            }
                        };
 
                        //текущий индекс меняем на предыдущий, будем продолжать с ним
                        current_ship_index.first=prev_ship_index;
                    }
                }
            }
        };
 
        for(auto c=scan_line.begin(); c!=scan_line.end(); c++, current_x++)
        {
            if(current_ship_index.second)
            {
                //предыдущая клетка была на корабле current_ship_index
 
                if(*c==water_char)
                {
                    //корабль current_ship_index закончился
                    current_ship_index.second=false;
                }
                else
                {
                    //корабль current_ship_index продолжается
 
                    //заполняем координату в текущей линии индексом корабля
                    curr_line_scanning[current_x]=current_ship_index.first;
 
                    //если можно, сливаем с кораблём предыдущей линии
                    MergeWithPrevLine();
                }
            }
            else
            {
                if(*c==water_char)
                {
                    //вода
                }
                else
                {
                    //новый корабль начался
                    current_ship_index=std::make_pair(ship_index_generator(),true);
 
                    //запоминаем координату на текущей линии
                    curr_line_scanning[current_x]=current_ship_index.first;
 
                    //если можно, сливаем с кораблём предыдущей линии
                    MergeWithPrevLine();
                }
            }
        }
 
        //скидываем текущую строку в ships_debug_list
        {
            if(scan_line.size()!=curr_line_scanning.size())
            {
                std::cout<<"line "<<file_line_index<<": scan_line must have same size as curr_line_scanning"<<'\n';
                return 0;
            }
 
            for(td_coord current_x=0; current_x<curr_line_scanning.size(); current_x++)
            {
                const auto c=scan_line[current_x];
                if(c==water_char)continue;
                ships_debug_list[curr_line_scanning[current_x]].cells[{current_x,current_y}]=c;
            }
        }
 
        prev_line_scanning.swap(curr_line_scanning);
        curr_line_scanning.clear();
 
        current_y++;
    }
 
    //вывод дебажной мапы с найденными кораблями
    std::cout<<"-------------------------"<<'\n';
    for(const auto& ship:ships_debug_list)
    {
        std::cout<<'\n';
        ship.second.Print(ship.first,hig,wid);
    }
 
    return 0;
}
дебажный вывод
Code
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
ship #1 = (3, 0) (4, 0) (4, 1) (5, 0) 
---SSS--
----S---
--------
--------
--------
--------
--------
--------
 
ship #2 = (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (1, 1) 
--------
XX------
X-------
X-------
X-------
X-------
X-------
X-------
 
ship #4 = (6, 1) (6, 2) 
--------
------X-
------S-
--------
--------
--------
--------
--------
 
ship #6 = (2, 2) 
--------
--------
--S-----
--------
--------
--------
--------
--------
 
ship #10 = (2, 4) (2, 5) (2, 6) (3, 4) (3, 6) (4, 4) (4, 6) (5, 4) (5, 6) (6, 4) (6, 5) (6, 6) 
--------
--------
--------
--------
--XXXXS-
--S---S-
--SXXXS-
--------
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
12.08.2020, 05:36
Цитата Сообщение от programmist- Посмотреть сообщение
И снова превышение памяти на том же тесте, что и бы в самый первый раз
Пришла в голову мысль, что в этой задаче не нужно хранить всё поле. Достаточно знать предыдущую строку. Не уверен, что правильно, но проверь
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
#include <iostream>
 
int main()
{
    int n, m;
    std::cin >> n >> m;
        
    int ans[4] = {};
    
    uint8_t arr[103 + 1] = {0};
    for(int i = 0; i < n; i++)
        for(int j = 0; j < m; j++)
        {
            char ch;
            std::cin >> ch;
            if (ch == '-')
            {
                arr[j] = 0;
                continue;
            }
 
            const uint8_t x =  arr[j] | (j != 0? arr[j - 1]: 0) | (arr[j]? arr[j + 1]: 0); 
            arr[j] = x | (ch == 'S'? 0x01: 0x02);
            if (arr[j] != x)
            {
                if (x != 0 && x != 0x03)
                    --ans[x];
                                    
                ++ans[arr[j]];
            }
        }
 
    std::cout  << ans[1] << " " << ans[2] << " " << ans[3];
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.08.2020, 05:36

Олимпиадная задача
program zad4; Var n,i,k:longint; c:char; Procedure closing; begin close(input); close(output); halt(0); end; ...

Олимпиадная задача
Задание 1. Написать и отладить программу, выполняющую задание. Подпрограмма должна быть рекурсивной. 2. Выполнить трассировку...

Олимпиадная задача
Провайдеры, предоставляющие услуги доступа в интернет широкому пользователю, часто составляют различную статистику посещений сайтов из...

Олимпиадная задача
Маленький мальчик, плывя с родителями вверх по речке, отпустил кораблик. После этого они прошли еще вверх 15 мин и сделали 30 мин....

олимпиадная задача
1)Отгадать целое число которое загадал компьютер в определённом диапазоне? 2)Lesson:В первом полугодии 2007-08 учебного года занятия...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Remote Connection Manager
DevAlt 21.06.2026
Написал для себя небольшую прилагу: https:/ / github. com/ altbodhi/ ReConMan По итогу пришел к мысли, что DU не дружат с существующими технологиями. От сериализации до отображения в реляционную. . .
Администрация Хабра удаляет новые энрегоэфективные алгоритмы, которые не западной школы кода, и вовсе никак не сгенерировавны.
Hrethgir 20.06.2026
Делается это, как замечено, при правках - при объявлении концептуальных отличий в алгоримах. Делается это, по линейке событий - после дополнения публикации основными отличиями от основных западных. . .
Процесс ориентированная диалектика (не новость - просто системное обновление, философия).
Hrethgir 20.06.2026
Однажды один участник в своём блоге, на этом форуме, сделал запись "О языках замолвите слово". Понимая, что язык - важная вещь, я решил хорошо подумать, прежде чем сказать, и сказал то, что вы видите. . .
Контроль уникальности строк в табличной части документа
Maks 18.06.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ПланированиеСпецтехники" с табличной частью "НаличиеОборудования", разработанного в КА2. Задача: контроль уникальности строк в. . .
Клиент
Uhbif79 18.06.2026
Здесь простой клиент для работы с сервером.
Сервер
Uhbif79 18.06.2026
Выкладываю простейший сервер.
Дефенестрация
kumehtar 18.06.2026
Узнал интересное слово. Дефенестрация. Это когда ты выбрасываешь кого-либо или что-либо из окна. Возьму на вооружение)))
Дихотомия добра и зла
kumehtar 18.06.2026
Как Дзен-буддисты говорят о добре и зле: не нужно воевать против зла, нужно воевать против невежества. Тогда добро станет ествественным, и поэтому вечным. Но дело в том, что невежество всё время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru