Помощь - Поиск - Пользователи - Календарь
Полная версия: Суммы элементов в матрице
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Fest
Такая вот у меня проблема:
Надо написать прогу, которая считает в квадратной матрице(5х5) суммы элементов треугольников. Треугольниками здесь называется такая вот весчь:
Матрица -
1 2 3 4 5
2 2 3 4 5
3 2 3 4 5
4 2 3 4 5
5 2 3 4 5

Вотс, надо вычислить в подобной матрице суммы красных треугольничков и зеленых. Проблема в том, как это сделать... Я пробовал просто складывать нужные элементы(s1:=a[1.2]+a[1.3] и так далее), но это немного не то. Можно ли как-нибудь еще посчитать суммы этих треугольников?
andriano
Если речь идет о матрицах фиксированного и не слишком большого размера, то это наиболее естественное и самое оптимальное решение. А способов можно придумать тысячи. Но оптимальный из них только один - в виде непосредственной суммы.
Fest
Цитата(andriano @ 23.12.2007 12:20) *

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

Спасибо. Интересно, а можно ли сделать какую-нить формулу, чтобы, допустим, считало эти треугольники (и не совсем треугольники, короче элементы, которые не затрагивают диагонали) в диапазоне квадратной матрицы от 5 до 10 допустим? Чтоб считало элементы, которые не лежат на диагоналях те, что вверху, внизу, слева и справа, отдельно от других "треугольников".
andriano
Можно, конечно.
Ручками (и глазками) ты ведь это можешь посчитать? Вот опиши подробно, как ты это делаешь - и будет тебе алгоритм.
Fest
Цитата(andriano @ 23.12.2007 19:24) *

Можно, конечно.
Ручками (и глазками) ты ведь это можешь посчитать? Вот опиши подробно, как ты это делаешь - и будет тебе алгоритм.

Я вроде пытался, но у меня не особо получается что-то. Математик из меня, как гений из маразматика :\ У меня с этим очень туговато... Можно хотя б какие-нить примеры?.. Чтоб можно было понять, как это вообще делать(на той стадии, когда массив заполняется значениями) , какие операции над циклом производить и тд. и тп.
andriano
Забудь пока о массивах и циклах. Представь, что перед тобой на бумаге несколько матриц разного размера. Как бы ты стал подсчитывать сумму?
klem4
на самом деле решение этой задачи не однократно выкладывалось, но не в таком виде как я щас сделал (я по крайней мере такого решения не припомню), проверок получается больше, но зато всего в 2 цикла все уместилось smile.gif

это конечно медленнее чем в несколько двойных циклов подсчитывать, но зато кода меньше, хоть это никаких плюсов и не дает ...

uses crt;

const
n = 5;

type
TMatrix = array [1..n, 1..n] of Integer;

procedure get_sum(const mx: TMatrix; var green, red: Integer);
var
i, j: Integer;
begin
green := 0;
red := 0;

for i := 1 to n do
for j := 1 to n do
if (i <> j) and (j <> n - i + 1) then begin
if ((j > i) and (j < n - i + 1)) or ((j > n - i + 1) and (j < i))
then red := red + mx[i, j]
else
green := green + mx[i, j];
end;
end;


const
mx: TMatrix = (
(1, 2, 3, 4, 5),
(2, 2, 3, 4, 5),
(3, 2, 3, 4, 5),
(4, 2, 3, 4, 5),
(5, 2, 3, 4, 5)
);

var
red_sum, green_sum: Integer;

begin
clrscr;
get_sum(mx, green_sum, red_sum);
writeln('red = ', red_sum);
writeln('green = ', green_sum);
readln;
end.
Fest
Цитата(andriano @ 23.12.2007 20:41) *

Забудь пока о массивах и циклах. Представь, что перед тобой на бумаге несколько матриц разного размера. Как бы ты стал подсчитывать сумму?

Стал бы тупо складывать нужные элементы smile.gif Другое дело сделать тоже самое в цикле, чтобы уже считало нужные элементы автоматически, с помощью какой-нить формулы. Например, чтобы нужные элементы считались, при этом не трогая диагоналей. У меня в голове это как-то не укладывается :\ Пытаюсь в мозгу вывести картинку, как это все происходит, но что-то не получается.

To Klem4:
Спасибо большое, но я похоже очень тупой :\ Можешь объяснить, как работает вот это:
for i := 1 to n do
for j := 1 to n do
if (i <> j) and (j <> n - i + 1) then begin
if ((j > i) and (j < n - i + 1)) or ((j > n - i + 1) and (j < i))

Что здесь с чем сравнивается?.. Что отнимается? Почему? Можешь прокомментировать, если не сложно?.. wacko.gif Желательно поподробей.


klem4
цикл по всем элемента матрицы
в цикле надо отобрать элементы, принадлежащие либо правому/левому, либо верхнему/нижнему треугольникам.

среди этих элементов нету ни одного, лежащего на диагоналях. Это мы и проверяем первым условием:

if (i <> j) and (j <> n - i + 1) then begin

если текущий элемент mx[i, j] не лежит на диагоналях, то проверим к какому виду треугольников он принадлежит:

if ((j > i) and (j < n - i + 1)) or ((j > n - i + 1) and (j < i))

если это условие даст истину, значит элемент лежит верхнем/нижнем треугольниках, иначе, так как мы уже исключили диагонали, он принадлежит правому/левому.

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



Fest
Цитата(klem4 @ 23.12.2007 22:20) *

цикл по всем элемента матрицы
в цикле надо отобрать элементы, принадлежащие либо правому/левому, либо верхнему/нижнему треугольникам.

среди этих элементов нету ни одного, лежащего на диагоналях. Это мы и проверяем первым условием:

if (i <> j) and (j <> n - i + 1) then begin

если текущий элемент mx[i, j] не лежит на диагоналях, то проверим к какому виду треугольников он принадлежит:

if ((j > i) and (j < n - i + 1)) or ((j > n - i + 1) and (j < i))

если это условие даст истину, значит элемент лежит верхнем/нижнем треугольниках, иначе, так как мы уже исключили диагонали, он принадлежит правому/левому.

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


Спасибо и на этом, попытаюсь вникнуть smile.gif good.gif
Еще один маленький вопросик!.. Как перевернуть матрицу на 90 градусов? Вроде надо поменять местами столбцы и строки, но у меня что-то не то получается. Делаю я вот так a[i,j]:=a[j,i]; где тут ошибка? Он у меня какую-то ересь выводит, не то, что надо :\
З.Ы. Если кто-то может объяснить то, что было выше, да так, чтобы даже полный чайник мог понять - никто не будет против, скорее всего все (включая меня) будут - за smile.gif (+ это потом можно будет кинуть в FAQ cool.gif )
klem4
Цитата
Как перевернуть матрицу на 90 градусов?


Решалось тоже, вроде даже в FAQ было, поищи.
мисс_граффити
Цитата
Делаю я вот так a[i,j]:=a[j,i]; где тут ошибка?

_здесь_ ошибки нет
а вот какие значения i и j ты берешь - загадка...

вообще - поиск (или FAQ) по слову транспонирование
Fest
Цитата(мисс_граффити @ 23.12.2007 23:05) *

_здесь_ ошибки нет
а вот какие значения i и j ты берешь - загадка...

вообще - поиск (или FAQ) по слову транспонирование

Прошу прощения за непонятные "феномены" smile.gifИ огромное спасибо за слово "транспонирование"... А то я тут ищу "перевернутые матрицы", "градусы" и прочую лабудень lol.gif lol.gif
andriano
Цитата(мисс_граффити @ 23.12.2007 23:05) *

Цитата
Делаю я вот так a[i,j]:=a[j,i]; где тут ошибка?

_здесь_ ошибки нет
а вот какие значения i и j ты берешь - загадка...
Не согласен.
Здесь мы теряем значение a[i,j]. В любом случае нужен буфер хотя бы на 1 элемент, а проще всего - на матрицу целиком.
andriano
Цитата(Fest @ 23.12.2007 21:59) *

Стал бы тупо складывать нужные элементы smile.gif
Угу.
А как ты определяешь, какие элементы являются нужными, а какие нет?
Цитата
Другое дело сделать тоже самое в цикле, чтобы уже считало нужные элементы автоматически, с помощью какой-нить формулы.
А "формула" и рождается из собственных рассуждений. Вот, скажем, верхний треугольник: начинаешь перебор со второго элемента первой строки, а заканчиваешь предпоследним, так?
Соответственно, и цикл можно записать:
for j := 1+1 to n-1 do
summ := summ + a[1,j];

Вторую стоку начинаешь считать на один элемент позже, а заканчиваешь - на 1 раньше:
for j := 1+2 to n-2 do
summ := summ + a[2,j];

Обращаем внимаение на то, что "добавка" в пределах суммирования совпадает с номером стоки
По высоте надо просуммировать n div 2 строк для нечетного n (каким и является 5). Если нарисовать для четного, то можно обнаружить, что две средние строки в суммровании не учавствуют, т.е. всего (n-2) div 2 строк.
То есть внешний цикл у нас должен суммировать строки от 1 до (n-1) div 2, (эта формула подходит как для четных, так и для нечетных размеров) а во внутреннем надо постепенно сужать строку, отнимая от начала и конца номер текущей строки:
for i := 1 to (n-1) div 2 do
for j := 1+i to n-i do
summ := summ + a[i,j];
Цитата
Например, чтобы нужные элементы считались, при этом не трогая диагоналей. У меня в голове это как-то не укладывается :\ Пытаюсь в мозгу вывести картинку, как это все происходит, но что-то не получается.
А ты увелич размер матрицы до 10-15 - понять будет легче.
Цитата

To Klem4:
Спасибо большое, но я похоже очень тупой :\ Можешь объяснить, как работает вот это:
for i := 1 to n do
for j := 1 to n do
if (i <> j) and (j <> n - i + 1) then begin
if ((j > i) and (j < n - i + 1)) or ((j > n - i + 1) and (j < i))

Что здесь с чем сравнивается?.. Что отнимается? Почему? Можешь прокомментировать, если не сложно?.. wacko.gif Желательно поподробей.

Это делает как раз то, что описано словами, а именно проводит перебор ПО ВСЕМ элементам, а прибавляет к сумме только нужные.
Я, кстати, предложил другой алгоритм: сразу перебирать только нужное. Как видишь, задача может решаться несколькими путями.
Fest
Всем большое спасибо! Особенно Andriano! Помог разобраться, объяснил smile.gif Поставил бы +, если бы мог smile.gif Сеня последняя полная луна в этом году ;) Все проясняется, щас лучшее время для свершения чего либо)
Michael_Rybak
Цитата
Поставил бы +, если бы мог


ok smile.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.