Компания ALT Linux
Опубликован: 07.03.2015 | Доступ: свободный | Студентов: 2135 / 486 | Длительность: 24:14:00
Лекция 6:

Статические и динамические матрицы

Задача 6.1. Найти сумму элементов матрицы, лежащих выше главной диагонали.

Алгоритм решения данной задачи (рис. 6.6) построен следующим образом: обнуляем ячейку для накапливания суммы (переменная s), затем с помощью двух циклов (первый по строкам, второй по столбцам) просматриваем каждый элемент матрицы, но суммируем только в том случае, если этот элемент находится выше главной диагонали (при выполнении условия i < j).

Блок-схема задачи 6.1 (алгоритм 1).

Рис. 6.6. Блок-схема задачи 6.1 (алгоритм 1).
Блок-схема задачи 6.1 (алгоритм 2).

Рис. 6.7. Блок-схема задачи 6.1 (алгоритм 2).

Текст программы:

#include <iostream>
using namespace std;
int main ( )
{
	int s, i, j, n,m, a [ 20 ] [ 20 ];
	cout<<" N = ";
	cin>>n;
	cout<<" M = ";
	cin>>m;
	cout<<"Ввод матрицы A "<<endl;
	for ( i =0; i<n; i++)
		for ( j =0; j<m; j++)
			cin>>a [ i ] [ j ];
	for ( s= i =0; i<n; i++)
		for ( j =0; j<m; j++)
			//Если элемент лежит выше главной диагонали, то наращиваем сумму.
			if ( j> i ) s+=a [ i ] [ j ];
	cout<<" S = "<<s<<endl;
}

На рис. 6.7 изображён ещё один алгоритм решения данной задачи. В нём проверка условия i < j не выполняется, но, тем не менее, в нём так же суммируются элементы матрицы, находящиеся выше главной диагонали. В нулевой строке заданной матрицы необходимо сложить все элементы, начиная с первого. В первой — все, начиная со второго, в i–й строке процесс начнётся с (i + 1)–го элемента и так далее. Таким образом, внешний цикл работает от 0 до N - 1, а второй от i+1 до M. Авторы надеются, что читатель самостоятельно составит программу, соответствующую описанному алгоритму.

Задача 6.2. Вычислить количество положительных элементов квадратной матрицы, расположенных по её периметру и на диагоналях. Напомним, что в квадратной матрице число строк равно числу столбцов.

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

Из условия задачи понятно, что не нужно рассматривать все элементы заданной матрицы. Достаточно просмотреть первую и последнюю строки, первый и последний столбцы, а так же диагонали. Все эти элементы отмечены на схеме, причём чёрным цветом выделены элементы, обращение к которым может произойти дважды. Например, элемент с номером (0, 0) принадлежит как к нулевой строке, так и к нулевому столбцу, а элемент с номером (N - 1,N - 1) находится в последней строке и последнем столбце одновременно. Кроме того, если N — число нечётное (на рис. 6.8 эта матрица расположена слева), то существует элемент с номером (N/2,N/2), который находится на пересечении главной и побочной диагоналей. При чётном значении N (матрица справа на рис. 6.8) диагонали не пересекаются.

Рисунок к задаче 6.2.

увеличить изображение
Рис. 6.8. Рисунок к задаче 6.2.

Итак, разобрав подробно постановку задачи, рассмотрим алгоритм её решения. Для обращения к элементам главной диагонали вспомним, что номера строк этих элементов всегда равны номерам столбцов. Поэтому, если параметр i изменяется циклически от 0 до N - 1, то A[i][i] — элемент главной диагонали. Воспользовавшись свойством, характерным для элементов побочной диагонали, получим:

i+j+1=N \longrightarrow j=N-i-1,
следовательно, для i = 0, 1,...,N - 1 элемент А[i][N-i-1] — элемент побочной диагонали. Элементы, находящиеся по периметру матрицы записываются следующим образом: А[0][i] — нулевая строка, А[N-1][i] — последняя строка и соответственно А[i][0] — нулевой столбец, А[i][N-1] — последний столбец.

Текст программы решения задачи с пояснениями приведён далее.

#include <iostream>
using namespace std;
int main ( )
{
	int k, i, j,N, a [ 20 ] [ 20 ];
	cout<<" N = ";
	cin>>N;
	cout<<"Ввод матрицы A "<<endl;
	for ( i =0; i<N; i++)
		for ( j =0; j<N; j++)
			cin>>a [ i ] [ j ];
	//k — количество положительных элементов матрицы,
	//расположенных по её периметру и на диагоналях.
	for ( i=k=0; i<N; i++)
	{
		if ( a [ i ] [ i ] >0) k++; //Элемент лежит на главной диагонали.
		if ( a [ i ] [ N-i -1]>0)k++; //Элемент лежит на побочной диагонали.
	}
	for ( i =1; i<N-1; i++)
	{
		if ( a [ 0 ] [ i ] >0) k++; //Элемент находится в нулевой строке.
		if ( a [N-1 ] [ i ] >0) k++; //Элемент находится в последней строке.
		if ( a [ i ] [ 0 ] > 0 ) k++; //Элемент находится в нулевом столбце.
		if ( a [ i ] [ N-1]>0)k++; //Элемент находится в последнем столбце.
	}
	//Элемент, находящийся на пересечении диагоналей, подсчитан дважды,
	//надо уменьшить вычисленное значение k на один.
	if ( (N%2!=0)&&(a [N/ 2 ] [N/2 ] >0) ) k--;
	cout<<" k = "<<k<<endl;
}
Сергей Радыгин
Сергей Радыгин

Символы кириллицы выводит некорректно. Как сделать чтобы выводился читабельный текст на русском языке?

Тип приложения - не Qt,

Qt Creator 4.5.0 основан на Qt 5.10.0. Win7.

 

Юрий Герко
Юрий Герко

Кому удалось собрать пример из раздела 13.2 Компоновка (Layouts)? Если создавать проект по изложенному алгоритму, автоматически не создается  файл mainwindow.cpp. Если создавать этот файл вручную и добавлять в проект, сборка не получается - компилятор сообщает об отсутствии класса MainWindow. Как правильно выполнить пример?