Статья Автор: Лебедев Дмитрий

Конспект 9. Двумерные массивы. Продолжение

Оглавление

Часть 1 Часть 2 Часть 3 Задачи
       
       

C++_Двумерные массивы. Продолжение. Часть 1

Задача об оценках по информатике

В классе учится n учеников. Каждый ученик получил итоговую оценку за работу по информатике. Все оценки — натуральные числа от 2 до 5. Необходимо для каждой оценки вывести список учеников, которые её получили. Считается, что все ученики в классе имеют номер от 1 до n. Их оценки заданы в порядке следования учеников.

Например, если в классе 4 ученика получили оценки 5, 2, 3, 5, то необходимо вывести следующую статистику:
2:2:
3:3:
4:
5:: 1 4

Решение

Создадим «вектор векторов» ans, в котором будем хранить список учеников, получивших каждую из оценок. Для удобства вектор будет иметь размер 6. Тогда для каждой оценки можно хранить список людей, её получивших, а списки в ячейках 0 и 1 останутся пустыми, так как оценок меньше 2 не существует по условию задачи. Будем последовательно считывать оценки и добавлять в список для данной оценки номер ученика, её получившего.

#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
    vector<vector<int> > ans(6);
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i){
        int mark;
        cin >> mark;
        ans[mark].push_back(i);
    }
    for (int mark = 2; mark <= 5; ++mark){
        cout << mark << ": ";
        for (int j = 0; j < ans[mark].size(); ++j)
            cout << ans[mark][j] << " ";
        cout << endl;
    }
    return 0;
}

C++_Двумерные массивы. Продолжение. Часть 2

Задача про игру «Сапёр»

На поле для игры в «Сапёр» клеточки с минами обозначаются символом «*», а в каждой пустой клеточке записано число от 0 до 8, равное количеству мин в 8 клетках, соседних с данной.

Дан список мин на поле. Постройте по данному списку изображение поля.

Решение

Заведём двумерный массив для хранения поля игры. В клетки, где стоят мины, будем записывать −1. В остальных клетках будем хранить, сколько мин являются соседями данной клетки. Заметим, что у клеток, которые находятся на краю поля, количество соседей меньше 8 (часть соседей находится вне поля). Поэтому для удобства мы увеличим размер поля с каждой из четырёх сторон на одну клетку. Теперь мы гарантируем, что у каждой клетки на изначальном поле ровно 8 соседей, и никакая операция просмотра соседней клетки не приведёт нас к выходу за пределы поля.

Упростим перебор всех соседей данной клетки. Для этого заведём массивы di и dj, каждый из которых будет иметь размер 8 и хранить сдвиг каждого соседа по вертикали и горизонтали соответственно.

#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
    int n, m, k;
    cin >> n >> m >> k;
    vector<vector<int> > t(n + 2, vector<int> (m + 2, 0));
    for (int i = 0; i < k; ++i){
        int mi, mj;
        cin >> mi >> mj;
        t[mi][mj] = -1;
    }
    vector<int> di = {-1, -1, -1,  0, 0,  1, 1, 1};
    vector<int> dj = {-1,  0,  1, -1, 1, -1, 0, 1};
    for (int i = 1; i < t.size() - 1; ++i){
        for (int j = 1; j < t[i].size() - 1; ++j){
            if (t[i][j] == -1){
                for (int k = 0; k < 8; ++k){
                    int ni = i + di[k];
                    int nj = j + dj[k];
                    if (t[ni][nj] != -1)
                        ++t[ni][nj];
                }
            }
        }
    }
    for (int i = 1; i < t.size() - 1; ++i){
        for (int j = 1; j < t[i].size() - 1; ++j){
            if (t[i][j] == -1){
                cout << "*";
            }
            else if (t[i][j] == 0){
                cout << ".";
            }
            else{
                cout << t[i][j];
            }
        }
        cout << endl;
    }
    return 0;
}

C++_Двумерные массивы. Продолжение. Часть 3

Задача про черепашку

В левом верхнем углу прямоугольной таблицы размером N×M находится черепашка. В некоторых клетках таблицы лежат монетки. Черепашка может перемещаться вправо или вниз, при этом маршрут черепашки заканчивается в правом нижнем углу таблицы. Необходимо определить, какое наибольшее количество монет сможет собрать черепашка.

Например, для таблицы

 

0 1 1 0
0 1 1 0
11 0 1 0

черепашка сможет собрать 4 монетки.

Решение

Будем хранить описание поля в таблице t. Заведём таблицу d. В di,j будем хранить максимальное количество монеток, которое может собрать черепашка, добравшись до клетки с координатами (i;j). В клетку (i,j) мы могли прийти только из двух клеток (i−1,j) и (i,j−1), а значит верно следующее соотношение: di,j=max(di−1,j,di,j−1)+ti,j.

Будем перебирать все клетки в таком порядке, чтобы при подсчёте ответа для текущей клетки уже было подсчитано значение таблицы d для клеток слева и сверху от неё. Заметим, что для этого подходит обычный перебор клеток таблицы «сверху-вниз, слева-направо».

У нашего решения могут быть проблемы при вычислении первого столбца и строки матрицы d. Чтобы их избежать, сделаем у таблицы d фиктивный столбец слева и строку сверху и заполним их нулями.

Ответ будет храниться в правой нижней клетке таблицы d.


Задачи для тренировки

1) Измерение температуры

 
2) Ходы коня  
3) Ходы ферзя  
4) Cамый дешёвый путь  
5) Количество маршрутов в прямоугольной таблице  
6) Шашку — в дамки  
7) Вывести маршрут максимальной стоимости  

Печать