IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Задача с двумерным массивом, Элементы равный сумме по...
Relrin
сообщение 1.12.2010 20:09
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


Дан массив A размерности n*m . Получить одномерный массив B, элементы которого получены путем суммирования элементов исходного массива , находящихся по периметрам.

В качестве примера, вот набросал, изображение такого рода:
Прикрепленное изображение

Прогресс не очень далеко, а может и нет. Работает правда этот кусочек кода для массива n*n, а вот для n*m ломаю голову... Пока дошел вот до этого:

k:=n div 2; 
for i:=1 to k do begin 
sum:=0; 
{строки} 
for j:=i to n-i+1 do 
sum:=sum+x[i,j]+x[n-i+1,j]; 
{столбцы} 
for j:=i+1 to n-i do 
sum:=sum+x[j,i]+x[j,n-i+1]; 
writeln(sum); {вывод суммы} 
end; 
if n mod 2=1 then 
writeln(x[k+1,k+1]);

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Relrin
сообщение 1.12.2010 20:34
Сообщение #2


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


Немного продвинулся вперед, однако, подсчитывает местами неправильно (скажем 3*3 считает правильно, если больше чем 3*3 - то уже неправильные подсчеты)
 
  k:=n div 2;
  p:=m div 2;
  for i:=1 to k do
  begin
    for d:=1 to p do
    begin
      sum:=0;
      {строки}
      for j:=i to n-i+1 do
        sum:=sum+a[i,j]+a[m-d+1,j];
      {столбцы}
      for j:=d+1 to m-i do
        sum:=sum+a[j,i]+a[j,n-i+1];
      b[count]:=sum;
      if count<=i then count:=count+1;
    end;
  end;
 
  if (n mod 2=1) and (m mod 2=1) and (n=m) then
    b[count]:=a[k+1,p+1];



Сообщение отредактировано: Relrin - 1.12.2010 20:34
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Krjuger
сообщение 1.12.2010 20:42
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Дам небольшую идею.Вот смотри,если матрица у нас не квадратная,и допустим n>m,то мы получим что строк больше столбцов (логично),но тогда у нас останется поледний центральный столбец,и несколько строк вместо одного центрального элемента,а если m>n,то ситуация получится обратной.Самое логичное разделить да 2 случая.Затем,поразмышляйте,как можно избавится от 2 внутрених циклов внутри for i:=1 to k do begin.Приглядитесь к ним,ведь они отличаются лиш чем?поменялись местами i,j и j вы учеличили на один)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Relrin
сообщение 1.12.2010 22:31
Сообщение #4


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


UP!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Lapp
сообщение 2.12.2010 7:12
Сообщение #5


Уникум
*******

Группа: Модераторы
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Боюсь, что все гораздо проще.. smile.gif
Способ, которым ты пошел, в корне порочен. Нет смысла обходить специальным образом, если все равно нужно просуммировать все. Основная идея - определить минимальное расстояние до края (расстояние до ближайшего края) массива. Это и будет "номер контура".
Вот тебе решение, разбирайся. Если будут вопросы - задавай, отвечу..

  if m<n then d:=(m-1)div 2+1 else d:=(n-1)div 2+1;  // calculating the b size
  for i:=1 to m do for j:=1 to n do begin
    k:=d;                      // set to max possible
    if i<k then k:=i;          // top distance
    if j<k then k:=j;          // left distance
    if m-i+1<k then k:=m-i+1;  // bottom distance
    if n-j+1<k then k:=n-j+1;  // right distance
    Inc(b[k],a[i,j]);          // adding to sum array
  end;


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Lapp
сообщение 2.12.2010 8:26
Сообщение #6


Уникум
*******

Группа: Модераторы
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


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

  if m<n then d:=(m-1)div 2+1 else d:=(n-1)div 2+1;  // calculate contours amount (size of b)
  for i:=1 to d do begin                             // cycle through contours
    for j:=i to m-i+1 do begin                       // rows (with edges)
      Inc(b[i],a[j,i]);
      if i<n-i+1 then Inc(b[i],a[j,n-i+1]);          // do not count a central row twice
    end;
    for j:=i+1 to n-i do begin                       // columns (edges excluded)
      Inc(b[i],a[i,j]);
      if i<m-i+1 then Inc(b[i],a[m-i+1,j]);          // do not count a central column twice
    end
  end;


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Relrin
сообщение 2.12.2010 13:40
Сообщение #7


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


Цитата(Lapp @ 2.12.2010 9:26) *

Но если ты все же хочешь выяснить, как решить эту задачу обходом по отдельным периметрам (контурам), то вот тебе другое решение. Рекомендую тебе с ним тоже разобраться, поскольку лучше свои ошибки понимать до конца.
  if m<n then d:=(m-1)div 2+1 else d:=(n-1)div 2+1;  // calculate contours amount (size of b)
  for i:=1 to d do begin                             // cycle through contours
    for j:=i to m-i+1 do begin                       // rows (with edges)
      Inc(b[i],a[j,i]);
      if i<n-i+1 then Inc(b[i],a[j,n-i+1]);          // do not count a central row twice
    end;
    for j:=i+1 to n-i do begin                       // columns (edges excluded)
      Inc(b[i],a[i,j]);
      if i<m-i+1 then Inc(b[i],a[m-i+1,j]);          // do not count a central column twice
    end
  end;


Спасибо! Немного уже раскрутил задачу с твоей помощью. Только проблема с подсчетом неквадратной матрицы осталась, т.к. подсчеты неправильные идут уже с первого элемента

Сообщение отредактировано: Relrin - 2.12.2010 14:44
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Relrin
сообщение 2.12.2010 15:48
Сообщение #8


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


Проблема в подсчете неквадратной матрицы в том(установлены проверками), что при n<m(пускай будет 3*4) считает 2ой элемент по вертикали, если n>m, то по горизонтали
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Relrin
сообщение 2.12.2010 16:36
Сообщение #9


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


Сейчас пытаюсь приделать условия к циклам. Отдельно считаем периметр если m>n и m<n... Нужна помощь blink.gif

if m<n then d:=(n-1)div 2+1 else d:=(m-1)div 2+1;
  for i:=1 to d do begin
    sum:=0;
    if count<=i then count:=count+1;
    {строки}
    for j:=i to m-i+1 do
    begin
      sum:=sum+a[j,i];
      if (i<n-i+1) and (m<=n) then sum:=sum+a[j,n-i+1];
      if (i<m-i+1) and (m>n)  then sum:=sum+a[j,m-i+1];
    end;
    {столбцы}
    for j:=i+1 to n-i do
    begin
      sum:=sum+a[i,j];
      if (i<m-i+1) and (m<=n) then sum:=sum+a[m-i+1,j];
      if (i<n-i+1) and (m>n)  then sum:=sum+a[n-i+1,j];
    end;
    b[count]:=sum;
  end;
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Relrin
сообщение 2.12.2010 21:03
Сообщение #10


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


UP!!!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Lapp
сообщение 3.12.2010 0:10
Сообщение #11


Уникум
*******

Группа: Модераторы
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Relrin @ 2.12.2010 13:40) *
Спасибо! Немного уже раскрутил задачу с твоей помощью. Только проблема с подсчетом неквадратной матрицы осталась, т.к. подсчеты неправильные идут уже с первого элемента
ЧТООО???... Эй, приятель.. Ты даешь себе отчет в том, что делаешь и пишешь?..
Я тебе дал ДВА ВЕРНЫХ РЕШЕНИЯ С ПОДРОБНЫМИ КОММЕНТАРИЯМИ. Они БЕЗУСЛОВНО работают со всеми матрицами любых соотношений длины и ширины. От тебя требовалось только переменные описать и ввести/вывести результат. Ты даже этого, не смог сделать, up'ник..

Хорошо, дополняю эти решения до целых программ.

Решение с обходом по контурам.
const
  m=3;
  n=4;
  l=(m+n-1) div 4 +1;

var
  a: array [1..m,1..n] of integer;
  i,j,d: integer;
  b: array [1..l] of integer;

begin
  for i:=1 to m do begin
    for j:=1 to n do begin
      a[i,j]:=Random(10);  
      Write(a[i,j]:4)
    end;
    WriteLn
  end;
  WriteLn;
  if m<n then d:=(m-1)div 2+1 else d:=(n-1)div 2+1;  // calculate contours amount (size of b)
  for i:=1 to d do begin                             // cycle through contours
    for j:=i to m-i+1 do begin                       // rows
      Inc(b[i],a[j,i]);
      if i<n-i+1 then Inc(b[i],a[j,n-i+1]);          // do not count last line twice
    end;
    for j:=i+1 to n-i do begin                       // columns
      Inc(b[i],a[i,j]);
      if i<m-i+1 then Inc(b[i],a[m-i+1,j]);          // do not count last column twice
    end
  end;
  for i:=1 to d do Write(b[i]:4);
  ReadLn
end.


Решение со сквозным подсчетом (лучше).
const
  m=4;
  n=4;
  l=(m+n-1)div 4+1;

var
  a: array [1..m,1..n] of integer;
  i,j,k,d: integer;
  b: array [1..l] of integer;

begin
  for i:=1 to m do begin
    for j:=1 to n do begin
      a[i,j]:=Random(10);
      Write(a[i,j]:4)
    end;
    WriteLn
  end;
  WriteLn;
  if m<n then d:=(m-1)div 2+1 else d:=(n-1)div 2+1;  // calculating the b size
  for i:=1 to m do for j:=1 to n do begin
    k:=d;                      // set to max possible
    if i<k then k:=i;          // top distance
    if j<k then k:=j;          // left distance
    if m-i+1<k then k:=m-i+1;  // bottom distance
    if n-j+1<k then k:=n-j+1;  // right distance
    Inc(b[k],a[i,j]);          // adding to summ array
  end;
  for i:=1 to d do Write(b[i]:4);
  ReadLn
end.


И кончай тут Up'ать каждый час. Тут не слепые собрались. Есть, что сказать - говори. А понукать будешь лошадей, когда сапоги выдадут..

-1 за нежелание вникать в ответы..


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 18.07.2025 7:20
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"