Как стать автором
Обновить

Комментарии 10

Спасибо.
Интересная задача. Но ИМХО нужно уточнить формулировку:
Итак, задача: разработать алгоритм для вычисления значения элемента спиральной матрицы на основании его координат [i, j] и размера самой матрицы, пользуясь только простыми арифметическими вычислениями. Исключение составляет модуль — абсолютное значение числа.

Матрица уже заполнена нулями или ее нужно инициализировать? Если нужно, то можно не только нулями? (Первым делом приходит идея вычислить элементы гл. диагонали до середины). Можно включить в циклы инициализации вспомогательный вектор с записями (структурами) i,j, где i,j — координаты элемента матрицы?
Там ниже есть условие «без условных переходов, или заготовленных данных, массивов и словарей». А элементы матрицы изначально заполнены нулями(это в первом коде есть).

А матрицу нельзя развернуть, заполнить и закрутить обратно? :)

Без ifов (во всяком случае на языке высокого уровня, кто знает как на машинный язык компилируется/интерпретируется) если получится, то можно. По сути выведение единой мат.формулы
Формулу можно упростить, если выводить её разворачивая спираль из центра с координатами (0,0) наружу — тогда N в формуле не будет. Чтобы привести её к исходному виду, нужно просто пересчитать координаты для конкретного N, а спираль развернуть вычитанием из максимального значения +1.
Можно попробовать и так, но предполагаю, что код меньше не станет (не пробовал — может кто и выведет покороче код). Если систему координат централизировать, то придется работать с отрицательными значениями — формула(если ее можно так назвать) будет такой же громоздкой. А вычитая из максимального значения, все равно придется использовать N (максимальное значение это — N * N). Ну вообщем как-то так.
Предложу
вариант решения
program tmp;
{Delpi 7}
{$APPTYPE CONSOLE}

uses
  SysUtils,System;
var
 M : array of array of integer; 
 N : integer;                   
 i,j,c : integer;               
 level, start, fin : integer; 
 v : integer;    
 stop: integer;  
begin
  write ('N=?');
  readln (N);
  SetLength(M,N+1,N+1); 
{
// 
  for i :=1 to N do
    for j:= 1 to N do
    M[i,j]:= 0;
//
 }


  v := 0;
  start := 0;
  fin   := N;
  i:= 1;
  stop := N * N div 2 + N mod 2;
  for level:=1 to stop do  // main loop
  begin
  start := start+1;
  for c:=start to fin do // from left to right
   begin
     v := v+1;
     M [i,c] := v;
     j := c;
   end;
   start := start+1;
  for c:=start to fin do // from top to bot
   begin
     v := v+1;
     M [c,j] := v;
     i := c;
   end;
  start := start-1;
  fin := fin-1;
  for c:=fin downto start do // from right to left
   begin
     v := v+1;
     M [i,c] := v;
     j := c;
   end;
  for c:=fin downto start+1 do // from bot to top+1
   begin
     v := v+1;
     M [c,j] := v;
     i := c;
   end;
  end;  // main loop

// print result
  for i :=1 to N do
   begin
   for j:= 1 to N do
    write (M[i,j]:3);
   writeln;
    end;
  writeln ('v=',v,'=N*N');  
  write ('Press anykey to exit...');  
  readln;

end.

2 цикла перебирают элементы матрицы, только вложенный порезан на 4 малых цикла для перечисления нужных участков строк и столбцов.
Отличное решение, только возможно ли в любой момент на основании координат (i, j) и размера матрицы получить значение любой ячейки? Через функцию.
Очевидно, возможно. Начиная с первого элемента обходить м-цу описанной процедурой, но не до конца (до полоного заполнения м-цы), а до элемента (i, j). Важно, что каждый элемент заполняется нужным значением только однажды, и оно не меняется. Можно оформить, как функцию от (i, j), которая возвратит искомое значение. Если предполагается, что вызовов функции будет много, то лучше обсчитать всю матрицу и просто читать значения нужных элементов.
Да это моя ошибка в условии задачи. Я не заложил там без «внутренних дополнительных циклов», хотя это подразумевалось. Кроме того, также считалось, что циклы сами состоят из условных переходов (условие выхода или входа, причем логически это заложено на «высоком» уровне). Мне следовало это обозначить.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории