Решение олимпиадных задач по информатике

Задачи, сгруппированные по методам решения. Метод вложенных матриц

Разбить на страницы
Показывать лекцию целиком

Рассмотрим задачу.

Задача 1: Заполнить двумерный массив размерностью NxN, как показано на рис.9.1 (ряд натуральных чисел указывает на направление обхода элементов):

(рис 9.1)

Идея решения: Мысленно "разберем" двумерный массив на четыре "вложенных" в исходный (рис.9.2). В каждом из них нужно заполнить ПОБОЧНУЮ ДИАГОНАЛЬ (опираясь на типовой алгоритм обработки квадратного массива относительно диагоналей):

(рис 9.2)

Итого, k изменяется от 1 до n:

for k=1 to n
 for i=1 to k
  a (i,k-i+1)= … 
 next  i
next k

Полное решение задачи на Бейсике:

input "n="; n
dim a(n,n)
x=1
for k=1 to n
 for i=1 to k
  a (i,k-i+1)= x
  x=x+1	
 next i
next k
rem=====================
for i=1 to n
 for j=1 to n
  print a (i,j);
 next j
 print
next i

Полное решение задачи на Паскале:

const m=10;
var a: array [1..m, 1..m] of byte;
 x, n, k, i: integer;
begin
 writeln ('n='); readln (n); x:=1;
 for k:=1 to n do
  for i:=1 to k do
   begin
   a [i,k-i+1]:=x;
   x:=x+1;	
   end;
 for i:=1 to n do
  begin
  for j:=1 to n do write (a [i,j]);
  writeln;
  end;
end.

Задача 2: Заполнить массив, как показано на табл.9.1:

1 1 1 1 1 1
1 2 2 2 2 2
1 2 3 3 2 1
1 2 3 3 2 1
1 2 2 2 2 1
1 1 1 1 1 1

Идея решения: Разложим исходную матрицу на "вложенные" (рис.9.3):

(рис 9.3)

Решение задачи на Бейсике:

Input "n="; n
Dim a(n,n)
for k=1 to n\2+1
 for i=k to n-k+1
  for j=k to n-k+1
   a (i,j)= k
  next j
 next i
next k
rem=====вывод======
for i=1 to n
 for j=1 to n
  print a (i,j);
 next j
 print
next i

Решение задачи на Паскале:

const m=10;
var a: array [1..m, 1..m] of byte;
 x, n, k, I, j: integer;
begin
 writeln ('n=');
 readln (n);
 for k:=1 to (n div 2 +1) do
  for i:=k to n-k+1 do
   for j:=k to n-k+1 do
	a [i,j]:= k;
 {=======вывод=========}
 for i:=1 to n do
  begin
  for j:=1 to n do
   write (a [i,j]);
  writeln;
  end;
end.

Задача 3: Заполнить массив, как показано на табл.9.2:

1 2 3 4 5 6
20 21 22 23 24 7
19 32 33 34 25 8
18 31 36 35 26 9
17 30 29 28 27 10
16 15 14 13 12 11

Дополнительные сведения: На таком заполнении массива базируется задача "скатерть Улама". В данной задаче квадратный массив заполняется по спирали (заполнение происходит не "вовнутрь", как в примере, а "изнутри" массива). Затем "вычеркиваются" все составные числа (см. задачу "Решето Эратосфена"). Оставшиеся на своих местах простые числа образуют причудливый узор, названный в честь автора "Скатертью Улама".

Идея решения: Разложим исходную матрицу на "вложенные". Каждую из "вложенных" матриц необходимо заполнить по периметру (рис.9.4).

(рис 9.4)

Решение на Бейсике:

input "n="; n
dim a (n,n)
x=1
for k=1 to n\2
 for i=k to n-k
  a(k,i)=x
  x=x+1 
 next 
 rem=============
 for i=k to n-k
  a(i,n-k+1)=x 
  x=x+1
 next 
 rem=============
for i=k to n-k
  a(n-k+1,n-i+1)=x
  x=x+1
 next 
 rem=============
for i=k to n-k
  a(n-i+1,k)=x
  x=x+1
 next i
next k
rem=================
for i=1 to n
 for j=1 to n
  print a(i,j);
 next j
 print
next i

Решение на Паскале:

const m=10;
var a: array [1..m, 1..m] of byte;
 x, n, k, i, j: integer;
begin
 writeln ('n='); readln (n);
 x:=1;
 for k:=1 to n div 2 do
  begin
  for i:=k to n-k do
    begin
	a [k,i]:=x;
	x:=x+1; 
	end;
  for i:=k to n-k do
	begin
	a [i,n-k+1]:=x; 
	x:=x+1;
	end 
  for i:=k to n-k do
	begin
	a [n-k+1,n-i+1]:=x;
	x:=x+1;
	end ;
  for i:=k to n-k do
	begin
	a [n-i+1,k]:=x;
	x:=x+1;
	end;
  end;
 {=======вывод========}
 for i:=1 to n do
  begin
  for j:=1 to n do write (a[i,j]);
  writeln;
  end;
end.

Задача 4: Заполните матрицу, как показано на рис.9.5:

(рис 9.5)

Дополнительные сведения: Есть в информатике классическая задача "Магический квадрат" (в "Магическом квадрате" сумма элементов всех строк, всех столбцов и всех диагоналей равна). Решать ее можно различными способами, один из которых называется методом "Террас". Для создания Магического квадрата размерностью n x n (n - нечетное число) необходимо заполнить двумерный массив размерностью (2n-1)x(2n-1) так, как в на рис.9.6:

(рис 9.6)

Затем "треугольники", выступающие за пределы жирной рамки перенести внутрь таким образом (табл.9.3):

3 16 9 22 15
20 8 21 14 2
7 25 13 1 19
24 12 5 18 6
11 4 17 10 23

В полученном двумерном массиве сумма элементов всех строк и всех столбцов равна.

Идея решения: Разбиваем исходную матрицу на "вложенные". В каждой матрице заполняем побочную диагональ:

(рис 9.7)

Решение очевидно.

Ключевые термины

  • Магический квадрат - двумерный массив, сумма элементов каждой строки, каждого столбца и каждой диагонали которого одинакова.
  • Метод "Террас" - способ создания магического квадрата
  • Решето Эратосфена - алгоритм нахождения простых чисел.
  • Скатерть Улама - узор из простых чисел, расположенных по спирали.
  • Краткие итоги

    При заполнении некоторых двумерных массивов проглядывается некоторая закономерность (способ заполнения повторяется). Мысленно "разберем" двумерный массив на "вложенные" - как бы независимые друг от друга массивы, для заполнения которых используется один и тот же способ. Разрабатываем для каждого из них алгоритм заполнения, затем находим зависимость, объединяющую все алгоритмы в один.

    Данный способ поможет решить такие задачи, как создание Магического квадрата методом "Террас", создание "Скатерти Улама" при помощи "Решета Эратосфена".

    Набор для практики

    Вопросы.

  • Каким образом можно заполнить двумерный массив числами натурального ряда чисел?
  • Каков порядок обхода элементов двумерного массива, если счетчик внешнего цикла используется в качестве первого индекса элемента массива, счетчик внутреннего цикла - в качестве второго индекса?
  • Каков порядок обхода элементов двумерного массива, если счетчик внешнего цикла используется в качестве второго индекса элемента массива, счетчик внутреннего цикла - в качестве первого индекса?
  • Упражнения.

  • Заполните массив по образцу (табл.9.4):

    1 2 3 4 5 6 7
    14 13 12 11 10 9 8
    15 16 17 18 19 20 21
    28 27 26 25 24 23 22
    и т.д. ... ... ... ... ... ...
    ... ...
  • Заполните массив по образцу (табл.9.5):

    1 2 6 7 15 16 28
    3 5 8 14 17 27
    4 9 13 18 26
    10 12 19 25
    11 20 24
    21 23
    22
  • Заполните массив по образцу (табл. 9.6):

    22 16 11 7 4 2 1
    23 17 12 8 5 3
    24 18 13 9 6
    25 19 14 10
    26 20 15
    27 21
    28
  • Страницы:

    Рассмотрим задачу.

    Задача 1: Заполнить двумерный массив размерностью NxN, как показано на рис.9.1 (ряд натуральных чисел указывает на направление обхода элементов):

    (рис 9.1)

    Идея решения: Мысленно "разберем" двумерный массив на четыре "вложенных" в исходный (рис.9.2). В каждом из них нужно заполнить ПОБОЧНУЮ ДИАГОНАЛЬ (опираясь на типовой алгоритм обработки квадратного массива относительно диагоналей):

    (рис 9.2)

    Итого, k изменяется от 1 до n:

    for k=1 to n
     for i=1 to k
      a (i,k-i+1)= … 
     next  i
    next k
    

    Полное решение задачи на Бейсике:

    input "n="; n
    dim a(n,n)
    x=1
    for k=1 to n
     for i=1 to k
      a (i,k-i+1)= x
      x=x+1	
     next i
    next k
    rem=====================
    for i=1 to n
     for j=1 to n
      print a (i,j);
     next j
     print
    next i

    Полное решение задачи на Паскале:

    const m=10;
    var a: array [1..m, 1..m] of byte;
     x, n, k, i: integer;
    begin
     writeln ('n='); readln (n); x:=1;
     for k:=1 to n do
      for i:=1 to k do
       begin
       a [i,k-i+1]:=x;
       x:=x+1;	
       end;
     for i:=1 to n do
      begin
      for j:=1 to n do write (a [i,j]);
      writeln;
      end;
    end.
    

    Задача 2: Заполнить массив, как показано на табл.9.1:

    1 1 1 1 1 1
    1 2 2 2 2 2
    1 2 3 3 2 1
    1 2 3 3 2 1
    1 2 2 2 2 1
    1 1 1 1 1 1

    Идея решения: Разложим исходную матрицу на "вложенные" (рис.9.3):

    (рис 9.3)

    Решение задачи на Бейсике:

    Input "n="; n
    Dim a(n,n)
    for k=1 to n\2+1
     for i=k to n-k+1
      for j=k to n-k+1
       a (i,j)= k
      next j
     next i
    next k
    rem=====вывод======
    for i=1 to n
     for j=1 to n
      print a (i,j);
     next j
     print
    next i
    

    Решение задачи на Паскале:

    const m=10;
    var a: array [1..m, 1..m] of byte;
     x, n, k, I, j: integer;
    begin
     writeln ('n=');
     readln (n);
     for k:=1 to (n div 2 +1) do
      for i:=k to n-k+1 do
       for j:=k to n-k+1 do
    	a [i,j]:= k;
     {=======вывод=========}
     for i:=1 to n do
      begin
      for j:=1 to n do
       write (a [i,j]);
      writeln;
      end;
    end.

    Задача 3: Заполнить массив, как показано на табл.9.2:

    1 2 3 4 5 6
    20 21 22 23 24 7
    19 32 33 34 25 8
    18 31 36 35 26 9
    17 30 29 28 27 10
    16 15 14 13 12 11

    Дополнительные сведения: На таком заполнении массива базируется задача "скатерть Улама". В данной задаче квадратный массив заполняется по спирали (заполнение происходит не "вовнутрь", как в примере, а "изнутри" массива). Затем "вычеркиваются" все составные числа (см. задачу "Решето Эратосфена"). Оставшиеся на своих местах простые числа образуют причудливый узор, названный в честь автора "Скатертью Улама".

    Идея решения: Разложим исходную матрицу на "вложенные". Каждую из "вложенных" матриц необходимо заполнить по периметру (рис.9.4).

    (рис 9.4)

    Решение на Бейсике:

    input "n="; n
    dim a (n,n)
    x=1
    for k=1 to n\2
     for i=k to n-k
      a(k,i)=x
      x=x+1 
     next 
     rem=============
     for i=k to n-k
      a(i,n-k+1)=x 
      x=x+1
     next 
     rem=============
    for i=k to n-k
      a(n-k+1,n-i+1)=x
      x=x+1
     next 
     rem=============
    for i=k to n-k
      a(n-i+1,k)=x
      x=x+1
     next i
    next k
    rem=================
    for i=1 to n
     for j=1 to n
      print a(i,j);
     next j
     print
    next i

    Решение на Паскале:

    const m=10;
    var a: array [1..m, 1..m] of byte;
     x, n, k, i, j: integer;
    begin
     writeln ('n='); readln (n);
     x:=1;
     for k:=1 to n div 2 do
      begin
      for i:=k to n-k do
        begin
    	a [k,i]:=x;
    	x:=x+1; 
    	end;
      for i:=k to n-k do
    	begin
    	a [i,n-k+1]:=x; 
    	x:=x+1;
    	end 
      for i:=k to n-k do
    	begin
    	a [n-k+1,n-i+1]:=x;
    	x:=x+1;
    	end ;
      for i:=k to n-k do
    	begin
    	a [n-i+1,k]:=x;
    	x:=x+1;
    	end;
      end;
     {=======вывод========}
     for i:=1 to n do
      begin
      for j:=1 to n do write (a[i,j]);
      writeln;
      end;
    end.

    Задача 4: Заполните матрицу, как показано на рис.9.5:

    (рис 9.5)

    Дополнительные сведения: Есть в информатике классическая задача "Магический квадрат" (в "Магическом квадрате" сумма элементов всех строк, всех столбцов и всех диагоналей равна). Решать ее можно различными способами, один из которых называется методом "Террас". Для создания Магического квадрата размерностью n x n (n - нечетное число) необходимо заполнить двумерный массив размерностью (2n-1)x(2n-1) так, как в на рис.9.6:

    (рис 9.6)

    Затем "треугольники", выступающие за пределы жирной рамки перенести внутрь таким образом (табл.9.3):

    3 16 9 22 15
    20 8 21 14 2
    7 25 13 1 19
    24 12 5 18 6
    11 4 17 10 23

    В полученном двумерном массиве сумма элементов всех строк и всех столбцов равна.

    Идея решения: Разбиваем исходную матрицу на "вложенные". В каждой матрице заполняем побочную диагональ:

    (рис 9.7)

    Решение очевидно.

    Ключевые термины

  • Магический квадрат - двумерный массив, сумма элементов каждой строки, каждого столбца и каждой диагонали которого одинакова.
  • Метод "Террас" - способ создания магического квадрата
  • Решето Эратосфена - алгоритм нахождения простых чисел.
  • Скатерть Улама - узор из простых чисел, расположенных по спирали.
  • Краткие итоги

    При заполнении некоторых двумерных массивов проглядывается некоторая закономерность (способ заполнения повторяется). Мысленно "разберем" двумерный массив на "вложенные" - как бы независимые друг от друга массивы, для заполнения которых используется один и тот же способ. Разрабатываем для каждого из них алгоритм заполнения, затем находим зависимость, объединяющую все алгоритмы в один.

    Данный способ поможет решить такие задачи, как создание Магического квадрата методом "Террас", создание "Скатерти Улама" при помощи "Решета Эратосфена".

    Набор для практики

    Вопросы.

  • Каким образом можно заполнить двумерный массив числами натурального ряда чисел?
  • Каков порядок обхода элементов двумерного массива, если счетчик внешнего цикла используется в качестве первого индекса элемента массива, счетчик внутреннего цикла - в качестве второго индекса?
  • Каков порядок обхода элементов двумерного массива, если счетчик внешнего цикла используется в качестве второго индекса элемента массива, счетчик внутреннего цикла - в качестве первого индекса?
  • Упражнения.

  • Заполните массив по образцу (табл.9.4):

    1 2 3 4 5 6 7
    14 13 12 11 10 9 8
    15 16 17 18 19 20 21
    28 27 26 25 24 23 22
    и т.д. ... ... ... ... ... ...
    ... ...
  • Заполните массив по образцу (табл.9.5):

    1 2 6 7 15 16 28
    3 5 8 14 17 27
    4 9 13 18 26
    10 12 19 25
    11 20 24
    21 23
    22
  • Заполните массив по образцу (табл. 9.6):

    22 16 11 7 4 2 1
    23 17 12 8 5 3
    24 18 13 9 6
    25 19 14 10
    26 20 15
    27 21
    28
  • Вернуться к учебному плану