Такая вот у меня проблема: Надо написать прогу, которая считает в квадратной матрице(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
23.12.2007 16:20
Если речь идет о матрицах фиксированного и не слишком большого размера, то это наиболее естественное и самое оптимальное решение. А способов можно придумать тысячи. Но оптимальный из них только один - в виде непосредственной суммы.
Fest
23.12.2007 21:21
Цитата(andriano @ 23.12.2007 12:20)
Если речь идет о матрицах фиксированного и не слишком большого размера, то это наиболее естественное и самое оптимальное решение. А способов можно придумать тысячи. Но оптимальный из них только один - в виде непосредственной суммы.
Спасибо. Интересно, а можно ли сделать какую-нить формулу, чтобы, допустим, считало эти треугольники (и не совсем треугольники, короче элементы, которые не затрагивают диагонали) в диапазоне квадратной матрицы от 5 до 10 допустим? Чтоб считало элементы, которые не лежат на диагоналях те, что вверху, внизу, слева и справа, отдельно от других "треугольников".
andriano
23.12.2007 23:24
Можно, конечно. Ручками (и глазками) ты ведь это можешь посчитать? Вот опиши подробно, как ты это делаешь - и будет тебе алгоритм.
Fest
23.12.2007 23:35
Цитата(andriano @ 23.12.2007 19:24)
Можно, конечно. Ручками (и глазками) ты ведь это можешь посчитать? Вот опиши подробно, как ты это делаешь - и будет тебе алгоритм.
Я вроде пытался, но у меня не особо получается что-то. Математик из меня, как гений из маразматика :\ У меня с этим очень туговато... Можно хотя б какие-нить примеры?.. Чтоб можно было понять, как это вообще делать(на той стадии, когда массив заполняется значениями) , какие операции над циклом производить и тд. и тп.
andriano
24.12.2007 0:41
Забудь пока о массивах и циклах. Представь, что перед тобой на бумаге несколько матриц разного размера. Как бы ты стал подсчитывать сумму?
klem4
24.12.2007 0:55
на самом деле решение этой задачи не однократно выкладывалось, но не в таком виде как я щас сделал (я по крайней мере такого решения не припомню), проверок получается больше, но зато всего в 2 цикла все уместилось
это конечно медленнее чем в несколько двойных циклов подсчитывать, но зато кода меньше, хоть это никаких плюсов и не дает ...
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;
Забудь пока о массивах и циклах. Представь, что перед тобой на бумаге несколько матриц разного размера. Как бы ты стал подсчитывать сумму?
Стал бы тупо складывать нужные элементы Другое дело сделать тоже самое в цикле, чтобы уже считало нужные элементы автоматически, с помощью какой-нить формулы. Например, чтобы нужные элементы считались, при этом не трогая диагоналей. У меня в голове это как-то не укладывается :\ Пытаюсь в мозгу вывести картинку, как это все происходит, но что-то не получается.
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))
Что здесь с чем сравнивается?.. Что отнимается? Почему? Можешь прокомментировать, если не сложно?.. Желательно поподробей.
klem4
24.12.2007 2: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))
если это условие даст истину, значит элемент лежит верхнем/нижнем треугольниках, иначе, так как мы уже исключили диагонали, он принадлежит правому/левому.
чтобы было понятней прогони алгоритм пошагово, анализируя каждый элемент. Объяснять я не мастак, сорри ...
Fest
24.12.2007 2:42
Цитата(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))
если это условие даст истину, значит элемент лежит верхнем/нижнем треугольниках, иначе, так как мы уже исключили диагонали, он принадлежит правому/левому.
чтобы было понятней прогони алгоритм пошагово, анализируя каждый элемент. Объяснять я не мастак, сорри ...
Спасибо и на этом, попытаюсь вникнуть Еще один маленький вопросик!.. Как перевернуть матрицу на 90 градусов? Вроде надо поменять местами столбцы и строки, но у меня что-то не то получается. Делаю я вот так a[i,j]:=a[j,i]; где тут ошибка? Он у меня какую-то ересь выводит, не то, что надо :\ З.Ы. Если кто-то может объяснить то, что было выше, да так, чтобы даже полный чайник мог понять - никто не будет против, скорее всего все (включая меня) будут - за (+ это потом можно будет кинуть в FAQ )
klem4
24.12.2007 2:45
Цитата
Как перевернуть матрицу на 90 градусов?
Решалось тоже, вроде даже в FAQ было, поищи.
мисс_граффити
24.12.2007 3:05
Цитата
Делаю я вот так a[i,j]:=a[j,i]; где тут ошибка?
_здесь_ ошибки нет а вот какие значения i и j ты берешь - загадка...
вообще - поиск (или FAQ) по слову транспонирование
Fest
24.12.2007 3:30
Цитата(мисс_граффити @ 23.12.2007 23:05)
_здесь_ ошибки нет а вот какие значения i и j ты берешь - загадка...
вообще - поиск (или FAQ) по слову транспонирование
Прошу прощения за непонятные "феномены" И огромное спасибо за слово "транспонирование"... А то я тут ищу "перевернутые матрицы", "градусы" и прочую лабудень
andriano
24.12.2007 12:01
Цитата(мисс_граффити @ 23.12.2007 23:05)
Цитата
Делаю я вот так a[i,j]:=a[j,i]; где тут ошибка?
_здесь_ ошибки нет а вот какие значения i и j ты берешь - загадка...
Не согласен. Здесь мы теряем значение a[i,j]. В любом случае нужен буфер хотя бы на 1 элемент, а проще всего - на матрицу целиком.
andriano
25.12.2007 0:17
Цитата(Fest @ 23.12.2007 21:59)
Стал бы тупо складывать нужные элементы
Угу. А как ты определяешь, какие элементы являются нужными, а какие нет?
Цитата
Другое дело сделать тоже самое в цикле, чтобы уже считало нужные элементы автоматически, с помощью какой-нить формулы.
А "формула" и рождается из собственных рассуждений. Вот, скажем, верхний треугольник: начинаешь перебор со второго элемента первой строки, а заканчиваешь предпоследним, так? Соответственно, и цикл можно записать:
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))
Что здесь с чем сравнивается?.. Что отнимается? Почему? Можешь прокомментировать, если не сложно?.. Желательно поподробей.
Это делает как раз то, что описано словами, а именно проводит перебор ПО ВСЕМ элементам, а прибавляет к сумме только нужные. Я, кстати, предложил другой алгоритм: сразу перебирать только нужное. Как видишь, задача может решаться несколькими путями.
Всем большое спасибо! Особенно Andriano! Помог разобраться, объяснил Поставил бы +, если бы мог Сеня последняя полная луна в этом году ;) Все проясняется, щас лучшее время для свершения чего либо)
Michael_Rybak
25.12.2007 8:34
Цитата
Поставил бы +, если бы мог
ok
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.