Задание:
Опишите на русском языке или на одном из языков программирования алгоритм определения количества положительных элементов квадратной матрицы, превышающих по величине среднее арифметическое всех элементов главной диагонали.
Решение:
В этой задаче нужно сначала найти среднее арифметическое всех элементов главной диагонали. Для этого требуется один простой (не вложенный!) цикл, потому что для элементов главной диагонали номер строки равен номеру столбца.
Пусть N (константа) – количество строк (и столбцов!) матрицы A. Введем вещественную переменную sred, в которой сначала подсчитаем сумму всех элементов главной диагонали. Введем целую переменную i, обозначающую номер строки. Запишем в sred начальное значение 0. В цикле изменяем i от 1 до N с шагом 1, добавляем к значению переменной sred значение элемента матрицы A[i,i]. После окончания цикла разделим sred на N (на главной диагонали всего N элементов), таким образом, в sred находится среднее значение элементов главной диагонали.
Теперь можно считать (только!) положительные элементы всей матрицы, которые больше sred. Вводим целочисленные переменные j (номер столбца) и count (счетчик «нужных» элементов) . В счетчик записываем начальное значение 0.
Организуем двойной цикл, перебирающий все комбинации (i,j) для i=1..N и j=1..N. В теле цикла проверяем элемент матрицы A[i,j]: если он больше нуля и больше sred, увеличиваем счетчик count на 1.
После окончания двойного цикла выводим значение count.
Программа может выглядеть так:
const N=5;
var A:array[1..N,1..N] of integer;
i, j, count: integer;
sred: real;
begin
for i:=1 to N do { ввод матрицы }
for j:=1 to N do readln(A[i,j]);
sred := 0; { находим сумму главной диагонали }
for i:=1 to N do
sred := sred + A[i,i];
sred := sred / N; { находим среднее }
count := 0; { считаем нужные элементы }
for i:=1 to N do
for j:=1 to N do
if (A[i,j] > 0) and (A[i,j] > sred) then
count := count + 1;
writeln(count)
end.
Заметим, что можно немного улучшить программу. В условном операторе в последнем двойном цикле можно заменить сложное условие простым, если вместо 0 и sred использовать максимальное из этих значений. Перед двойным циклом нужно добавить оператор
if sred < 0 then sred := 0;
а условный оператор изменить так:
if A[i,j] > sred then
count := count + 1;
Во-вторых, можно немного более грамотно обработать условие A[i,j] > sred. Дело в том, что при делении в операторе
sred := sred / N; { находим среднее }
может получиться вещественное число (с дробной частью). Вещественные числа (за редким исключением ) хранятся в памяти компьютера неточно, потому что в двоичном коде содержат (теоретически) бесконечное число разрядов. Поэтому лучше НЕ делить полученную сумму sred на N, а для проверки вместо условия A[i,j] > sred/N использовать равносильное ему A[i,j]*N > sred. Плюс в том, что в последнем случае все операции выполняются с целыми числами и ошибок из-за неточного представления дробных чисел в памяти гарантированно не будет. Однако, есть и минус: вместо одного деления (на всю программу) придется выполнять N2 умножений (для каждого элемента матрицы). Вот еще одна версия программы:
const N=5;
var A:array[1..N,1..N] of integer;
i, j, count: integer;
sred: real;
begin
for i:=1 to N do { ввод матрицы }
for j:=1 to N do readln(A[i,j]);
sred := 0; { находим сумму главной диагонали }
for i:=1 to N do
sred := sred + A[i,i];
count := 0; { считаем нужные элементы }
if sred < 0 then sred := 0;
for i:=1 to N do
for j:=1 to N do
if A[i,j]*N > sred then
count := count + 1;
writeln(count)
end.