Помощь - Поиск - Пользователи - Календарь
Полная версия: Задача с двумерным массивом
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Relrin
Дан массив 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]);

Relrin
Немного продвинулся вперед, однако, подсчитывает местами неправильно (скажем 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];

Krjuger
Дам небольшую идею.Вот смотри,если матрица у нас не квадратная,и допустим n>m,то мы получим что строк больше столбцов (логично),но тогда у нас останется поледний центральный столбец,и несколько строк вместо одного центрального элемента,а если m>n,то ситуация получится обратной.Самое логичное разделить да 2 случая.Затем,поразмышляйте,как можно избавится от 2 внутрених циклов внутри for i:=1 to k do begin.Приглядитесь к ним,ведь они отличаются лиш чем?поменялись местами i,j и j вы учеличили на один)
Relrin
UP!
Lapp
Боюсь, что все гораздо проще.. 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;
Lapp
Но если ты все же хочешь выяснить, как решить эту задачу обходом по отдельным периметрам (контурам), то вот тебе другое решение. Рекомендую тебе с ним тоже разобраться, поскольку лучше свои ошибки понимать до конца.

  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
Цитата(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
Проблема в подсчете неквадратной матрицы в том(установлены проверками), что при n<m(пускай будет 3*4) считает 2ой элемент по вертикали, если n>m, то по горизонтали
Relrin
Сейчас пытаюсь приделать условия к циклам. Отдельно считаем периметр если 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;
Relrin
UP!!!
Lapp
Цитата(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 за нежелание вникать в ответы..
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.