Упражнения

A: Диагонали параллельные главной

Дано число \(n\). Создайте массив размером \(n\times n\) и заполните его по следующему правилу. На главной диагонали должны быть записаны числа 0. На двух диагоналях, прилегающих к главной, числа 1. На следующих двух диагоналях числа 2, и т.д.

Решение оформите в виде функции

vector <vector<int>> solution(int n)

Сдайте на проверку только тело функции.

Значение \(n\) Полученный массив
5
0 1 2 3 4
1 0 1 2 3
2 1 0 1 2
3 2 1 0 1
4 3 2 1 0

B: Побочная диагональ

Дано число \(n\). Создайте массив размером \(n\times n\) и заполните его по следующему правилу:

Числа на диагонали, идущей из правого верхнего в левый нижний угол равны 1.

Числа, стоящие выше этой диагонали, равны 0.

Числа, стоящие ниже этой диагонали, равны 2.

Решение оформите в виде функции

vector <vector<int>> solution(int n)

Сдайте на проверку только тело функции.

Значение \(n\) Полученный массив
4
0 0 0 1
0 0 1 2
0 1 2 2
1 2 2 2

C: Поменять столбцы

Дан двумерный массив и два числа \(i\) и \(j\). Поменяйте в массиве столбцы с номерами \(i\) и \(j\). и выведите результат.

Решение оформите в виде функции

void swap_columns(vector<vector<int>> & a, int i, int j)

Сдайте на проверку только тело функции.

Параметры функции Изменённый масив
11 12 13 14
21 22 23 24
31 32 33 34

\(i=0\)

\(j=1\)

12 11 13 14
22 21 23 24
32 31 33 34

D: Симметричен ли массив?

Дан массив размером \(n\times n\). Проверьте, является ли этот массив симметричным относительно главной диагонали.

Решение оформите в виде функции

bool is_symmetric(vector<vector<int>> & a)

Сдайте на проверку только тело функции.

Решение не должно выполнять лишних действий.

Входной массив Возвращаемое значение
3
0 1 2
1 2 3
2 3 4
true

E: k-я диагональ

Дан квадратный двумерный массив размером \(n\times n\) и число \(k\). Выведите элементы \(k\)-й по счету диагонали ниже главной диагонали (т.е. если \(k=1\), то нужно вывести элементы первой диагонали, лежащей ниже главной, если \(k=2\), то второй диагонали и т.д.).

Значение \(k\) может быть отрицательным, например, если \(k=-1\), то нужно вывести значение первой диагонали лежащей выше главной. Если \(k=0\), то нужно вывести элементы главной диагонали.

Решение оформите в виде функции

vector<int> kth_diagonal(vector<vector<int>> & a, int k)

Сдайте на проверку только тело функции.

Сложность этой функции должна быть \(O(n - |k|)\) (число элементов на диагонали равно \(n-|k|\)), то есть в функции не должно быть переборов всех элементов массива вложенными циклами, нельзя просматривать лишние элементы.

Параметры функции Изменённый масив
1 2 3 4
5 6 7 8
0 1 2 3
4 5 6 7

\(k=1\)

5 1 6
1 2 3 4
5 6 7 8
0 1 2 3
4 5 6 7

\(k=-2\)

3 8

F: Поменять две диагонали

Дан квадратный массив. Поменяйте местами элементы, стоящие на главной и побочной диагонали, при этом каждый элемент должен остаться в том же столбце (то есть в каждом столбце нужно поменять местами элемент на главной диагонали и на побочной диагонали).

Решение оформите в виде функции

void swap_diagonals(vector<vector<int>> & a)

Сдайте на проверку только тело функции.

Параметры функции Изменённый масив
1 2 3
4 5 6
7 8 9
7 2 9
4 5 6
1 8 3

G: Заполнение змейкой

По данным числам \(n\) и \(m\) заполните двумерный массив размером \(n\times m\) числами от 1 до \(nm\) “змейкой”, как показано в примере.

Решение оформите в виде функции

vector<vector<int>> fill(int n, int m)

Сдайте на проверку только тело функции.

Параметры функции Полученный массив

\(n=3\)

\(m=5\)

   1   2   3   4   5
10 9 8 7 6
11 12 13 14 15

H: Транспонировать прямоугольную матрицу

Дан двумерный массив размером \(n\times m\). Симметричный ему относительно главной диагонали массив называется транспонированным к данному. Он имеет размеры \(m \times n\): строки исходного массива становятся столбцами транспонированного, столбцы исходного массива становятся строками транспонированного.

Для данного массива постройте транспонированный массив. на экран. Решение оформите в виде функции

vector<vector<int>> transpose(const vector<vector<int>> & a)

Сдайте на проверку только тело функции.

Исходный массив Полученный массив
11 12 13 14
21 22 23 24
31 32 33 34
11 21 31
12 22 32
13 23 33
14 24 34

I: Транспонировать квадратную матрицу

Дан двумерный массив размером \(n\times n\). Транспонируйте его и результат запишите в этот же масссив. Вспомогательный массив использовать нельзя.

Решение оформите в виде функции

void transpose(vector<vector<int>> & a)

Сдайте на проверку только тело функции.

Исходный массив Полученный массив
1 2 3
4 5 6
7 8 9
1 4 7
2 5 8
3 6 9

J: Число маршрутов короля

В левом верхнем углу доски размером \(n\times m\) стоит шахматный король. За один ход он может сделать ход вправо, вниз или на одну клетку по диагонали вправо-вниз. Посчитайте количество маршрутов, ведущий из левого верхнего угла доски в правый нижний.

Программа получает на вход размеры доски (числа \(n\) и \(m\) и должна вывести число искомых маршрутов. На проверку сдаётся программа целиком.

Ввод Вывод
3 4
25

K: Одномерный массив в двумерный

Дан одномерный массив из \(n\times m\) элементов. Сделайте из него двумерный массив из \(n\) строк по \(m\) элементов в каждой.

Решение оформите в виде функции

vector<vector<int>> convert(const vector<int> & src, int n, int m)

Сдайте на проверку только тело функции.

Параметры функции Полученный массив
0 1 2 3 4 5 6 7 8 9

\(n=2\)

\(m=5\)

0 1 2 3 4
5 6 7 8 9

L: Заполнение в шахматном порядке

Даны числа \(n\) и \(m\). Заполните массив размером \(n \times m\) в шахматном порядке: клетки одного цвета заполнены нулями, а другого цвета заполнены числами натурального ряда сверху вниз, слева направо. В левом верхнем углу записано число 1.

Решение оформите в виде функции

vector<vector<int>> fill(int n, int m)

Сдайте на проверку только тело функции.

Параметры функции Полученный массив

\(n=3\)

\(m=5\)

1 0 2 0 3
0 4 0 5 0
6 0 7 0 8

M: Поворот прямоугольного массива

Дан прямоугольный массив размером \(n\times m\). Поверните его на 90 градусов по часовой стрелке, записав результат в новый массив размера \(m\times n\).

Решение оформите в виде функции

vector<vector<int>> rotate(const vector<vector<int>> & src)

Сдайте на проверку только тело функции.

Исходный массив Полученный массив
11 12 13 14
21 22 23 24
31 32 33 34
31 21 11
32 22 12
33 23 13
34 24 14

N: Поворот квадратного массива

Дан квадратный массив. Поверните его на 90 градусов по часовой стрелке. Результат запишите в этот же массив, вспомогательный массив использовать нельзя.

Решение оформите в виде функции

void rotate(vector<vector<int>> & src)

Сдайте на проверку только тело функции.

Исходный массив Полученный массив
1 2 3
4 5 6
7 8 9
7 4 1
8 5 2
9 6 3

O: Заполнение диагоналями

По данным числам \(n\) и \(m\) заполните двумерный массив размером \(n\times m\) числами от 1 до \(nm\) “диагоналями”, как показано в примере.

Решение оформите в виде функции

vector<vector<int>> fill(int n, int m)

Сдайте на проверку только тело функции.

Параметры функции Полученный массив

\(n=3\)

\(m=5\)

 1  2  4  7 10
3 5 8 11 13
6 9 12 14 15

P: Сапер

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

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

Программа получает на вход числа N и M - количество строк и столбцов на поле, а также количество мин на поле K. Далее идет K пар чисел - координат мин. Первое число - номер строки, второе число - номер столбца.

Выведите изображение поля на экран, клетки при выводе разделяйте одним пробелом.

Ввод Вывод
3 2 2
1 1
2 2
* 2
2 *
1 1
2 2 0
0 0
0 0

Q: Домино

Проводя генеральную уборку на дачном чердаке, Саша нашел в комоде кучу доминошек из разных наборов. Каждая доминошка представляет собой прямоугольник, разделенный на две половинки. На каждой из половинок нарисовано от 0 до 6 точек. Ориентации доминошки не имеют — их можно как угодно поворачивать.

В совсем раннем детстве Саша видел, как играют в домино: суть игры заключается в том, что надо брать доминошку и как можно громче колотить ею об стол, крича при этом «рыба!». Услышав доносящийся с чердака грохот, наверх поднялся Сашин дедушка. Он смог объяснить Саше настоящие правила игры в домино: игроки составляют длинную цепочку, в которой соседние доминошки касаются половинками с одинаковым числом точек.

Саше решил называть «дружными доминошками» пару доминошек, которые можно поставить в игре рядом (т.е. доминошки в паре соприкасаются половинками с равными числами) в том или ином порядке. Играть в домино ему не с кем, поэтому Саша развлекается тем, что всевозможными способами составляет пары и считает количество «дружных доминошек».

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

В первой строке входного файла содержится натуральное число \(N\) — количество доминошек (\(1 \le N ≤ 100000\)).

В каждой из последующих строк содержится описание доминошки: два целых числа \(X\) и \(Y\) (\(0 \le X, Y \le 6\)) — количество точек на каждой из половинок доминошки.

Выведите одно число — количество пар «дружных доминошек».

Ввод Вывод
2
1 2
2 1
1
5
1 2
2 3
3 1
4 3
4 3
8

Примечание. Во втором тесте дружными являются следующие пары: 1-2 2-3, 1-2 3-1, 2-3 3-1, 2-3 4-3, 2-3 4-3, 3-1 4-3, 3-1 4-3, 4-3 4-3

R: Покер-3

\(K\) человек играют в покер по правилам, описанным в задании предыдущего листка. Каждый получает на руки \(N\) карт возможных значений от \(1\) до \(N\).

Пронумеруем игроков числами от 1 до \(K\). Упорядочите их по невозрастанию силы комбинации их карт, а при одинаковой силе комбинаций — по возрастанию номера игрока.

По значениям карт двух игроков определите, кто выигрывает.

Первая строка входных данных содержит числа \(K\) и \(N\) — количество игроков и количество карт на руках у каждого из них, \(1\le K\times N\le 10^5\). Следующие \(K\) строк содержат по \(N\) натуральных чисел от 1 до \(N\) каждое — значения карт каждого игрока.

Программа должна вывести перестановку чисел 1, ..., \(K\).

Ввод Вывод
5 4
3 2 1 4
2 3 3 3
1 1 2 2
1 1 2 1
2 1 3 2
2 4 3 5 1

S: Заполнение спиралью

По данным числам \(n\) и \(m\) заполните двумерный массив размером \(n\times m\) числами от 1 до \(nm\) по спирали, выходящей из левого верхнего угла и закрученной по часовой стрелке, как показано в примере.

Решение оформите в виде функции

vector<vector<int>> fill(int n, int m)

Сдайте на проверку только тело функции.

Параметры функции Полученный массив

\(n=4\)

\(m=5\)

 1  2  3  4  5
14 15 16 17 6
13 20 19 18 7
12 11 10 9 8

T: Жизнь

Автор игры “Жизнь” британский математик Джон Конвей скончался 11 апреля 2020 г. от осложнений коронавирусной инфекции в Нью-Джерси, США.

Наиболее известный пример клеточного автомата  — игра “Жизнь” — устроен по следующим правилам. В каждой клетке клетчатого поля может жить микроорганизм. Для клетки подсчитывается количество соседних с ней клеток (по стороне или по углу), в которых есть микроорганизмы.

  1. Все микроорганизмы, у которых менее двух соседей, умирают от скуки.
  2. Все микроорганизмы, у которых более трех соседей, умирают от перенаселенности.
  3. В пустых клетках, у которых ровно три живых соседа, появляется новый микроорганизм.

Все изменения происходят одновременно, то есть для каждой клетки сначала выясняется ее судьба, а затем происходят изменения сразу во всех клетках. Можно считать, что каждую секунду происходит обновление всех клеток по указанным правилам. Требуется по данной конфигурации определить, во что она превратится через T секунд.

В первой строке входных данных записаны два натуральных числа — размер квадратного поля \(N\) (\(1 \le N \le 10\)) и время \(T\) (\(1 \le T \le 100\)). Далее записано \(N\) строк по \(N\) чисел, описывающих начальную конфигурацию (0 — пустая клетка, 1 — микроорганизм). Числа в строках разделены пробелами.

Необходимо вывести \(N\) строк по \(N\) чисел — описание конфигурации через \(T\) секунд.

Ввод Вывод
3 1
1 0 1
1 0 1
1 0 1
0 0 0
1 0 1
0 0 0
2 2
1 1
1 1
1 1
1 1
5 10
1 0 1 1 0
0 1 0 0 0
0 0 0 1 0
0 0 0 0 0
0 1 0 1 0
0 1 1 0 0
0 1 1 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

U: Робот

Петя написал программу движения робота. Программа состоит из следующих команд:

S — сделать шаг вперед.

L — повернуться на 90 градусов влево.

R — повернуться на 90 градусов вправо.

Напишите программу, которая по заданной программе для робота определит, сколько шагов он сделает прежде, чем впервые вернется на то место, на котором уже побывал до этого, либо установит, что этого не произойдет.

Программа получает на вход строку из заглавных латинских букв S, L, R, описывающую программу для робота. Общее число команд в программе не превышает 200, при этом команд S — не более 50.

Программа должна вывести, сколько шаго будет сделано (то есть выполнено команд S) прежде, чем робот впервые окажется в том месте, через которое он уже проходил. Если такого не произойдет, выведите в выходной файл число –1.

Ввод Вывод
SSLSLSLSSRSRS
5
LSSSS
-1

V: “Магический” квадрат

Заполните квадратную таблицу \(N\times N\) нулями и единицами так, чтобы в любом квадрате размером \(K\times K\) было ровно \(S\) единиц.

Программа получает на вход числа \(N\), \(K\), \(S\) (\(1\le N\le 100\), \(1\le K\le N\), \(0\le K\le S^2\)).

Выведите полученную таблицу, разделяя числа пробелами. Если решений несколько, можно вывести любое из них.

Ввод Вывод
3 2 1
0 0 0
0 1 0
0 0 0
4 2 2
1 0 0 1
0 1 1 0
1 0 0 1
0 1 1 0

W: Крестики-нолики

Напишите программу, которая по изображению поля для игры в «Крестики-нолики» определит, могла ли такая ситуация возникнуть в результате игры с соблюдением всех правил.

Напомним, что игра в «Крестики-нолики» ведется на поле 3×3. Два игрока ходят по очереди. Первый ставит крестик, а второй – нолик. Ставить крестик и нолик разрешается в любую еще не занятую клетку поля. Когда один из игроков поставит три своих знака в одной горизонтали, вертикали или диагонали, или когда все клетки поля окажутся заняты, игра заканчивается.

Вводится три строки по три числа в каждой, описывающих игровое поле. Число 0 обозначает пустую клетку, 1 – крестик, 2 – нолик. Числа в строке разделяются пробелами.

Требуется вывести слово YES, если указанная ситуация могла возникнуть в ходе игры, и NO в противном случае.

Тесты к этой задаче закрытые.

Ввод Вывод
1 1 1
1 1 1
1 1 1
NO
2 1 1
1 1 2
2 2 1
YES
1 1 1
2 0 2
0 0 0
YES
0 0 0
0 1 0
0 0 0
YES
1 1 1
2 2 2
0 0 0
NO

ZA: Настоящий магический квадрат

Магическим квадратом порядка \(N\) называется квадратная матрица размера \(N \times N\) , составленная из чисел 1, 2, ..., \(N^2\) так, что суммы чисел в каждом столбце, каждой строке и каждой из двух больших диагоналей равны между собой. Напишите программу, которая строит магический квадрат заданного порядка \(N\).

Программа получает на вход одно число \(N\), \(3\le N\le 100\) и должна вывести магический квадрат порядка \(N\).

Ввод Вывод
4
16 2 3 13 
5 11 10 8 
9 7 6 12 
4 14 15 1