If (b<a[1,1]) or(b>a[m,n]) then
Goto 10;
For i:=2 tom do
If b<a[i,1] then
Begin
For j:=1 to n do
If b=a[i-1,j] then
Begin
is:=i-1; js:=j; { найден элемент, равный b }
Goto10
End;
Goto 10; { в строке нет элемента, равного b }
End;
For j:=1 to n do{ просмотр эл-тов последней строки }
Ifb=a[m,j] then
Begin
is:=i-1; js:=j; Goto 10
End;
10:
Writeln('is = ',is,' js = ',js);
End.
В программе Task208a среди 20 строк раздела операторов содержатся четыре оператора Goto. Хотя эти операторы использованы для принудительного выхода из цикла, столь большая их плотность вызывает сомнения в хорошем стиле программы. Если вместо цикла Forиспользовать цикл While,то операторы Gotoможно исключить из программы:
Begin
В в о д m, n, A, b
is:=0; js:=0;
If (b>=a[1,1]) and (b<=a[m,n]) then
Begin
i:=2; Cond:=true;
While(i<=m) and Cond do
Begin
Ifb<a[i,1] then
Begin
j:=1;
While (j<=n) and Cond do
Begin
If b=a[i-1,j] then
Begin
is:=i-1; js:=j; { найден элемент, }
Cond:=false { равный b }
End;
Inc(j);
End;
Cond:=false; { в строке нет элемента,равного b }
End;
Inc(i);
End;
If is=0 then { просмотр эл-тов последней строки }
Begin
j:=1; Cond:=true;
While(j<=n) and Cond do
Begin
Ifb=a[m,j] then
Begin
is:=i-1; js:=j; Cond:=false
End;
Inc(j);
End;
End;
End;
Writeln('is = ',is,' js = ',js);
End.
Вариант 2. Более эффективным является двоичный поиск, для которого среднее количество сравнений равно ln( )/ln(2) (см.Task116). Однако алгоритм двоичного поиска, использованный в задаче 1.18, определен лишь по отношению к одномерному массиву.
По индексам и элемента матрицы можно определить его порядковый номер , где - количество элементов в строке матрицы (количество столбцов). Тогда появляется возможность обработки матрицы как одномерного массива.
В программе требуется решать также обратную задачу: по порядковому номеру определить индексы соответствующего элемента . Для этого можно использовать формулы
i = (k-1) div n + 1; .
ProgramTask208b;
Label10;
ConstMmax = 30; Nmax = 50;
Type Matrix = array[1..Mmax,1..Nmax] of integer;
Var m,n, { размер матрицы }
is,js, { позиция элемента, равного b }
i,j : byte;
k,k1,k2 : word;
b : integer;
A : Matrix; { исходная матрица }
Begin
В в о д m, n, A, b
k1:=1; k2:=m*n;
is:=0; js:=0;
While k1<=k2 do
Begin
k:=(k1+k2) div2;
i:=(k-1) divn + 1; j:=k-(i-1)*n;
If b=a[i,j] then
Begin
is:=i; js:=j; Goto 10
End
Else
If b<a[i,j] then
k2:=k-1
Else
k1:=k+1;
End;
10:
Writeln('is = ',is,' js = ',js);
End.
Пример 9.
Элементы каждой строки прямоугольной матрицы сдвинуть циклически вправо, не затрагивая при этом положения максимального элемента.
Например, для строки
6 12 -4 17 1 0 9 11 14
получим
14 6 12 17 -4 1 0 9 11
Program Task209;
Label10;
ConstMmax = 30; Nmax = 50;
TypeMatrix = array[1..Mmax,1..Nmax] ofreal;
Var i,j,jmax,m,n : byte;
Amax,R : real;
A : Matrix;
Begin
В в о д m, n, A
Fori:=1 to m do{ Перебор строк матрицы }
Begin
Amax:=a[i,1]; jmax:=1; { Определение положения }
For j:=2 to n do{ макс.элемента в i-ой строке }
If a[i,j]>Amax then
Begin
Amax:=a[i,j]; jmax:=j
End;
If jmax=1 then{ Максимальный элемент - }
Begin {первый в строке}
R:=a[i,n];
Forj:=n downto 3 do
a[i,j]:=a[i,j-1];
a[i,2]:=R;
End
Else
If jmax=n then{ Максимальный элемент - }
Begin { последний в строке }
R:=a[i,n-1];
For j:=n-1 downto2 do
a[i,j]:=a[i,j-1];
a[i,1]:=R;
End
Else{ Максимальный элемент занимает }
Begin { промежуточное положение }
R:=a[i,n]; { в строке }
For j:=n downto jmax+2 do
a[i,j]:=a[i,j-1];
a[i,jmax+1]:=a[i,jmax-1];
For j:=jmax-1 downto 2 do
a[i,j]:=a[i,j-1];
a[i,1]:=R;
End;
End;
П е ч а т ь A
End.
Пример 10.
Нулевые элементы каждого столбца прямоугольной матрицы переместить в начало этого же столбца, сохранив без изменения последовательность расположения остальных его элементов.
Program Task210;
Const Mmax = 30; Nmax = 50;
Type Matrix = array[1..Mmax,1..Nmax] of integer;
Vari,j,iz,k,m,n : byte;
A : Matrix;
Begin
В в о д m, n, A
For j:=1 to n do
Begin
k:=0;
For i:=1 tom do
If a[i,j]=0 then
Begin
Inc(k);
For iz:=i downto k+1 do
a[iz,j]:=a[iz-1,j];
a[k,j]:=0;
End;
End;
П е ч а т ь А
End.
Пример 11.
Элементы каждого столбца прямоугольной матрицы сгруппировать в порядке возрастания их расстояния от среднего арифметического значения элементов этого столбца, где .
ProgramTask211;
Const Mmax = 30; Nmax = 50;
Type Matrix = array[1..Mmax,1..Nmax] of real;
Vector = array[1..Mmax] of real;
Var i,j,k,m,n : byte;
S : real;
Cond : boolean;
A : Matrix;
D : Vector;
Begin
В в о д m, n, A
For j:=1 to n do
Begin
S:=0; { Определение среднего }
For i:=1 to m do{ арифметического значения S }
S:=S+a[i,j]; { элементов j-го столбца }
S:=S/m;
For i:=1 to m do{ Определение расстояний d }
d[i]:=abs(S-a[i,j]); { для элементов столбца }
Cond:=true; k:=m-1;
While Cond do{ Группировка элементов }
Begin { столбца по возрастанию }
Cond:=false; k:=m-1;{ параметра d }
For i:=1 to k do
If d[i]>d[i+1] then
Begin
S:=a[i,j]; a[i,j]:=a[i+1,j]; a[i+1,j]:=S;
S:=d[i]; d[i]:=d[i+1]; d[i+1]:=S;
Cond:=true;
End;
Dec(k);
End;
End;
П е ч а т ь A
End.
Пример 12.
Элементы, расположенные на периметре прямоугольной матрицы, сдвинуть по часовой стрелке на один шаг.
ProgramTask212;
Const Mmax = 30; Nmax = 50;
Type Matrix = array[1..Mmax,1..Nmax] of real;
Var i,j,m,n : byte;
R : real;
A : Matrix;
Begin
В в о д m, n, A
R:=a[1,1]; { Сохранение левого верхнего эл-та }
For i:=1 tom-1 do{ Сдвиг левого столбца вверх }
a[i,1]:=a[i+1,1];
For j:=1 to n-1 do { Сдвиг нижней строки влево }
a[m,j]:=a[m,j+1];
Fori:=m downto 2 do { Сдвиг правого столбца вниз }
a[i,n]:=a[i-1,n];
Forj:=n downto3 do{ Сдвиг первой строки вправо }
a[1,j]:=a[1,j-1];
a[1,2]:=R; { Запись сохраненного элемента }
П е ч а т ь А
End.
Пример 13.
Допустимым преобразованием матрицы называют перестановку двух строк или двух столбцов. Для заданной прямоугольной матрицы с помощью допустимых преобразований добиться того, чтобы один из элементов матрицы, обладающий наибольшим по модулю значением, располагался в левом верхнем углу матрицы.
Program Task213;
Const Mmax = 30; Nmax = 50;
Type Matrix = array[1..Mmax,1..Nmax] of integer;
Vari,j,imax,jmax,m,n : byte;
R,Amax : integer;
A : Matrix;
Begin
В в о д m, n, A
Amax:=abs(a[1,1]); { Определение положения }
imax:=1; jmax:=1; { максимального элемента }
For i:=1 tom do
For j:=1 to n do
If abs(a[i,j])>Amax then
Begin
Amax:=a[i,j]; imax:=i; jmax:=j;
End;
Ifimax>1 then{ Обмен элементов строк }
For j:=1 ton do { с номерами 1 и imax }
Begin
R:=a[1,j]; a[1,j]:=a[imax,j]; a[imax,j]:=R;
End;
Ifjmax>1 then{ Обмен элементов столбцов }
For i:=1 tom do{ с номерами 1 и jmax }
Begin
R:=a[i,1]; a[i,1]:=a[i,jmax]; a[i,jmax]:=R;
End;
П е ч а т ь imax, jmax, Amax, A
End.
Пример 14.
Найти максимальный среди всех элементов тех строк матрицы, которые упорядочены (либо по возрастанию, либо по убыванию).
Числовая последовательность считается упорядоченной по возрастанию, если
(в отличие от строгой упорядоченности, при которой должны соблюдаться отношения ).
Функция SignGroup в программе Task214 для -ой строки матрицы вначале производит поиск первой пары неравных друг другу элементов. При этом булевской переменной присваивается значение true, если второй элемент этой пары больше первого элемента, и значение false в противном случае. После этого проверяется, нет ли нарушения установленного порядка между остальными парами элементов -ой строки. Если в строке все элементы одинаковы, то такая строка считается упорядоченной.
ProgramTask214;
ConstMmax = 30; Nmax = 50;
TypeMatrix = array[1..Mmax,1..Nmax] of integer;
Vari,j,imax,jmax,m,n : byte;
Amax : integer;
A : Matrix;
{ ------------------------------------ }
Function SignGroup(k:byte):boolean;
{ Определение упорядоченности элементов k-ой строки }
Label10;
Varj : byte;
b : boolean;
Begin
b:=true;
Forj:=1 to n-1 do
If a[k,j]<>a[k,j+1] then
Begin
b:=a[k,j]<a[k,j+1]; Goto 10
End;
10:
SignGroup:=true;
If b then
Forj:=2 ton-1 do
If a[k,j]>=a[k,j+1] then
Begin
SignGroup:=false; Exit
End;
If not b then
For j:=2 to n-1 do
If a[k,j]<=a[k,j+1] then
Begin
SignGroup:=false; Exit
End;
End { SignGroup };
{ ------------------------------------ }
Begin
В в о д m, n, A
imax:=0; jmax:=0; Amax:=0;
For i:=1 to m do
IfSignGroup(i) then
If imax=0 then{ встретилась первая }
Begin { упорядоченная строка }
Amax:=a[i,1]; imax:=i; jmax:=1;
For j:=2 to n do
If a[i,j]>Amax then
Begin
Amax:=a[i,j]; jmax:=j;
End;
End
Else
For j:=1 ton do{ рассматривается очередная }
If a[i,j]>Amax then{ упорядоченная строка }
Begin
Amax:=a[i,j]; imax:=i; jmax:=j;
End;
Writeln('imax = ',imax,' jmax = ',jmax,' Amax = ',Amax);
End.
Пример 15.
В прямоугольной матрице рассмотреть квадратные подматрицы размерностью 1, 2, 3, ... , причем для всех подматриц левым верхним элементом является элемент исходной матрицы с индексами (1,1). Определить номер подматрицы, среднее арифметическое значение элементов которой является максимальным.
Program Task215;
ConstMmax = 30; Nmax = 50;
Type Matrix = array[1..Mmax,1..Nmax] of integer;
Vari,j,k,kmax,m,n,p : byte;
S,Smax : real;
A : Matrix;
Begin
В в о д m, n, A
Ifm>n then{ p = min(m,n) }
p:=n
Else
p:=m;
Smax:=a[1,1]; kmax:=1;
For k:=2 top do
Begin
S:=0;
For i:=1 to k do
Forj:=1 tok do
S:=S+a[i,j];
S:=S/sqr(k);
If S>Smax then
Begin
Smax:=S; kmax:=k;
End;
End;
П е ч а т ь kmax, Smax
End.
Пример 16.
Соседями элемента матрицы называют элементы, смежные с ним по вертикали и по горизонтали. Элемент матрицы называется локальным минимумом, если он строго меньше всех имеющихся у него соседей. Подсчитать количество локальных минимумов заданной прямоугольной вещественной матрицы. Учесть, что локальный минимум не может находиться на периметре матрицы.
Program Task216;
Const Mmax = 30; Nmax = 50;
Type Matrix = array[1..Mmax,1..Nmax] of real;
Var i,j,m,n,
Count : byte; { счетчик локальных минимумов }
R : real;
Cond : boolean;
A : Matrix;
Begin
В в о д m, n, A
Count:=0;
For i:=2 tom-1 do
For j:=2 to n-1 do
Begin
R:=a[i,j];
Cond:=(R<a[i,j-1]) and (R<a[i,j+1]) and
(R<a[i-1,j]) and (R<a[i+1,j]);
If Cond then
Inc(Count);
End;
Writeln('Count = ',Count);
End.
Пример 17.
Известно, что в прямоугольной целочисленной матрице два и только два элемента равны между собой. Определить их индексы.
Указание. В программе не должно быть двухкратного сравнения одних и тех же элементов.
Здесь, как и в задаче 8, нужно рассматривать матрицу как одномерный массив, индексация которого определяется порядковыми номерами элементов матрицы.
Program Task217;
Label10;
Const Mmax = 30; Nmax = 50;
Type Matrix = array[1..Mmax,1..Nmax] of integer;
Var i1,j1, { индексы эл-та с порядковым номером k1 }
i2,j2, { индексы эл-та с порядковым номером k2 }
m,n : byte; { кол-во строк и столбцов матрицы }
k1,k2, { порядковые номера элементов матрицы }
p : word; { количество элементов матрицы }
Cond : boolean;
A : Matrix; { исходная матрица }
Begin
В в о д m, n, A
p:=m*n; Cond:=false;
For k1:=1 top-1 do
Begin
i1:=(k1-1) div n + 1; j1:=k1-(i1-1)*n;
For k2:=k1+1 to p do
Begin
i2:=(k2-1) div n + 1; j2:=k2-(i2-1)*n;
If a[i1,j1]=a[i2,j2] then
Begin
Cond:=true; Goto10;
End;
End;
End;
10:
IfCond then
Writeln('i1=',i1,' j1=',j1,' i2=',i2,' j2=',j2)
Else
Writeln('В матрице нет одинаковых элементов');
End.
Пример 18.
Для заданной целочисленной квадратной матрицы , имеющей элементов, проверить, имеет ли место хотя бы однократное совпадение -ой строки и -го столбца ( ).
Program Task218;
Label 10;
Const Nmax = 40;
TypeMatrix = array[1..Nmax,1..Nmax] of integer;
Var j,k,n : byte;
Cond : boolean;
A : Matrix;
Begin
В в о д m, n, A
k:=0;
Repeat
Cond:=true; Inc(k);
For j:=1 ton do
If a[k,j]<>a[j,k] then { Выход из цикла просмотра }
Begin{ строки при обнаружении }
Cond:=false; Goto10 { несовпадающих элементов }
End;
10:
Until Cond or(k=n);
IfCond then
Writeln('Cовпадение строки и столбца с номером ',k)
Else
Writeln('Нет совпадающих строки и столбца');
End.
Цикл Repeatзаканчивает свою работу, если найдены совпадающие строка и столбец (Cond = true) или просмотрены все строки и соответствующие им столбцы (k = n).
Пример 19.
Две строки матрицы линейно зависимы, если одну из них можно получить из другой умножением на постоянный коэффициент. Определить, имеются ли в прямоугольной вещественной матрице линейно зависимые строки и указать номера первой пары таких строк.
ProgramTask219;
Label 10;
Const eps = 0.001; Mmax = 30; Nmax = 50;
TypeMatrix = array[1..Mmax,1..Nmax] ofreal;
Var i,j,k,i1,i2,m,n : byte;
R,R1 : real;
Cond : boolean;
A : Matrix;
Begin
В в о д m, n, A
For i:=1 to n-1 do
Fork:=i+1 to n do
Begin
R:=a[i,1]/a[k,1]; Cond:=true;
Forj:=2 to n do
Begin
R1:=a[i,j]/a[k,j];
Ifabs(R-R1)>eps then
Cond:=false;
End;
IfCond then Goto 10;
End;
10:
IfCond then
Writeln('Линейно зависимы строки ',i,' и ',k)
Else
Writeln('В матрице нет линейно зависимых строк');
End.
Сравнение вещественных переменных R и производится по параметру .
Пример 20.
Подсчитать количество строк целочисленной прямоугольной матрицы , элементы которых являются перестановкой чисел 1, 2, ..., .
Program Task220;
Const Mmax = 30; Nmax = 50;
Type Matrix = array[1..Mmax,1..Nmax] of integer;
Var i,j,k,m,n : byte;
Cond : boolean;
A : Matrix;
{ --------------------------------- }
Function Permut(k:byte):boolean;
{ true, если k-ая строка является перестановкой 1 .. n }
Var j,nk : byte;
R : integer;
Bol : boolean;
Begin
Bol:=true; nk:=n-1; { Группировка строки }
While Bol do{ по возрастанию }
Begin
Bol:=false;
For j:=1 tonk do
Ifa[k,j]>a[k,j+1] then
Begin
R:=a[k,j]; a[k,j]:=a[k,j+1]; a[k,j+1]:=R;
Bol:=true;
End;
Dec(nk);
End;
Permut:=true; { Проверка равенства между }
For j:=1 ton do{ значением элемента и его }
If a[k,j]<>j then { порядковым номером }
Begin
Permut:=false; Exit;
End;
End{ Permut };
{ --------------------------------- }
Begin
В в о д m, n, A
k:=0;
Fori:=1 to m do
IfPermut(i) then
Inc(k);
Writeln('k = ',k);
End.
Пример 21.
Определить, имеется ли в прямоугольной целочисленной матрице хотя бы одна симметричная строка, элементы которой монотонно изменяются от начала до ее середины (по возрастанию или по убыванию).
ProgramTask221;
Label 10;
ConstMmax = 30; Nmax = 50;
Type Matrix = array[1..Mmax,1..Nmax] of integer;
Var i,k,m,n : byte;
Cond : boolean;
A : Matrix;
{ --------------------------------- }
Function SignRow(k:byte):boolean;
{ Проверка симметричности и строгой упорядоченности }
{ элементов k-ой строки }
Var i,j : byte;
CondSim,CondHigh : boolean;
Begin
CondSim:=true; SignRow:=true;{Проверка симметричности}
i:=1; j:=n; { элементов строки }
While i<j do