Программирование

Давайте здесь устроим поле для обсуждения неясных моментов программирования на Паскале

Кстати, Александр Петров ...

... меня зовут Валерий Шахамболетович!

Валерий Шахамболетович

Большое спасибо.

Извините,можно пожалуйста

Извините,можно пожалуйста спросить,шаг изменения счетчика в цикле "For" может изменяться только на 1 или можно самой устанавливать значение этого шага?

цикл for

Насколько мне известно можно изменять значение i в цикле в зависимости от условий.
Например:

  1. ....
  2. for i:= 1 to n do begin
  3. ....
  4. if B then i:=i+С {где B какое либо Булеантное выражение и С - целое число (так же можно вместо плюса подставить минус или умножение, деление не рекомендуеться)}
  5. ....

Однако Валерий Шахамболетович не одобряет таких действий, с изменением значения цикла внутри этого самого цикла. Старые версии паскаля так же не допускали данной операции, но последние версии разрешают изменение цикла.
С помощью таких операций удобно посчитать например сумму нечетных чисел. Например, нам нужно посчитать сумму первых n нечетных чисел:
  1. Program ne4etnie;
  2. var n,i,sum:Integer;
  3. begin
  4. read(n);
  5. sum:=0;
  6. for i:=1 to 2n do begin {умножаем введеное число на 2 т.к. при выполнении цикла мы посчитаем только сумму n/2 чисел, например если мы ввели 10, то программа посчитает только сумму первых 5 нечетных чисел, а нам требуеться сумма 10}
  7. sum:=sum+i;
  8. i:=i+1; {когда цикл начнеться i будет равно 1, после присваивания i=2, а когда мы снова начинаем цикл значение i увеличиваеться на 1, тем самым мы зайдем в цикл уже со следующего числа, т.е. 3}
  9. end;
  10. write(sum)
  11. end.

Марии, о for

Автоматическое изменение параметра цикла For (а только такое и может быть рекомендовано!) в Паскале возможно ТОЛЬКО НА 1 ДИСКРЕТ в сторону увеличения (for-to) или уменьшения (for-downto). Любые другие законы изменения, в частности с шагом 2 или -2 требуют использования более общих операторов while или repeat.

Евгению о for

1. Об изменении параметра цикла:
Вы пишите...

  1. ...
  2. if B then i:=i+С {где B какое либо Булеантное выражение и С - целое число (так же можно вместо плюса подставить минус или умножение, деление не рекомендуеться)}
  3. ...

Мои замечания: C - не обязательно целое (см. лекции). В заголовке оператора цикла ошибка. Насчёт особого статуса деления так же не понятно. Кроме того, странный термин "Булеантное"

2. Программа ne4etnie - очень экзотичное, мягко говоря, "решение".
Вот три правильных решения задачи суммирования первых N нечётных, натуральных чисел:

  1. //с циклом for
  2. ...
  3. S:=0;
  4. for i:= 1 to N do begin
  5.    S:=S+ 2*i-1;
  6. end;
  7. ...
Недостаток этого первого решения - замедление за счёт операции умножения в теле цикла.

  1. // c циклом while
  2. ...
  3. S:=0; i:=1; L:=(2*N);
  4. While i <= L do Begin
  5.   Inc(S,i); Inc(i,2);
  6. End;
  7. ...
Это второе решение может быть рекомендовано, как наиболее логичное и эффективное во многих задачах с не единичным шагом параметра цикла.

  1. // вообще без цикла (только для данной частной задачи)
  2. ...
  3. // арифм. прогрессия с разностью 2 и числом членов N
  4. M:=1 + 2*(N-1); // последний член прогрессии
  5. S:=(1 + M)*N div 2; // формула суммы ар. прогрессии
  6. ...
Конечно, это третье решение - безусловно, лучшее (правда, пригодное конкретно, только для этой задачи), т.к. время работы теперь не только мало, но и вообще не зависит от длины последовательности.

...

Извиняюсь, я имел в виду булевское выражение, перепутал что-то...

Что касаеться особого статуса деления, то при делении мы можем получить число, требующее тип Real, что может при дальнейших вычислениях требовать более сложных решений, лично я бы не эксперементировал с этим, ведь всегда можно найди другой путь, в данном случае без деления, чтобы получить более точные данные и более понятную программу.

А что сказать на счет ваших задач, спасибо большое за примеры, они пригодятся в дальнейшем, но я не ставил перед собой цель написать программу для вычисления суммы нечетных чисел, её я написал для более наглядной реализации моих мыслей и знаний по данной теме. Так что, не судите строго, если у меня присутствуют ошибки в программе.

Ещё раз о делении

1. Ещё раз о делении. Пора запомнить. Бывает 2 деления: целочисленное (div) и вещественное (/).
Когда мы обсуждаем значения параметре цикла for, даже РЕЧИ НЕ МОЖЕТ БЫТЬ о Real, т.к. он не является порядковым (снова см. лекции!).
В Вашем примере, говорится только о целых. Деление, сответственно, может быть только div. При этом, при рабте с целыми, оно вполне допустимо и ничем не "хуже" сложения, вычитания или умножения. А тип real (и операция "/"), о которых говорите Вы, здесь вообще не должно упоминаться.
И ни к каким "сложным решениям" грамотное применение div, конечно не приводит.

Например, в лёгкой вариации условия Вашей задачи, если было бы нужно суммировать не первых N, а все нечётные натуральные, не превышающие N, то мы записали бы:
 ... for i:=1 to (N+1) div 2  do  S:=S + 2*i -1; ...
и применение деления в данном контексте вполне было бы уместным.

2. Я тоже не ставил перед собой цель, показать как решается конкретно задача Вашего примера. Я показал ОБЩИЕ ПРИЁМЫ организации цикла с параметром, имеющим не единичный шаг, на Вашем же примере. Мне казалось, что это понятно.
Что же, до Вашей конкретной задачи о суммировании нечётных, то ей я посвятил третье решение, много раз подчеркнув, что как раз оно (и только оно) направлено на эту частную задачу.

Вообщем

Теперь все понятно, спасибо за подробные разъяснения насчет деления и цикле for в целом, думаю они пригодяться всем читателям форума.

Матрицы

В курсе АТЧ мы сейчас проходим матрицы. Почему бы не попробовать писать программы по тому что мы проходим? Это думаю, будет отличной тренировкой...
Я больше рассчитываю конечно, на выпускников колледжа, ибо они уже знакомы с паскалем, но буду очень рад услышать вопросы и предложения других студентов.
В общем - начнём... Вот моя программка по нахождению определителя матрицы.

  1. Program delta1;
  2. type
  3.     array2=array[1..8, 1..8] of integer;   //двумерный массив (тип для использования в подпрограммах)
  4. var
  5.   Application: delta;
  6.   A:array2;   //массив
  7.   m,i,j:byte; //м-размерность массива
  8.  
  9. procedure showArray (B:array2; n:byte); //вывод массива в виде матрицы, н-размерность
  10. var i,j:byte;
  11. begin
  12.      for i:=1 to n do
  13.      begin
  14.           for j:=1 to n do
  15.           write(B[i,j],' ');
  16.           writeln;
  17.      end;
  18. end;
  19.  
  20. function getArray (B:array2; n,x,y:byte):array2; //получения массива вычёркиванием х-строки и у-столбца
  21. var i,i1,j,j1:byte;
  22. C:array2;   //массив для результатов
  23. begin        //i,j - счётчики для В... i1,j1 - счётчики С
  24.      i:=0; i1:=1;
  25.      while i<n do //циклы следят за массивом В
  26.      begin
  27.           j1:=1;  j:=0; //инициализация переменных для столбцов на каждой итерации "строчного" цикла
  28.           inc(i);
  29.           if i<>x then   //если текущая строка не равна вычёркиваемой...
  30.           begin
  31.                while j<n do
  32.                begin
  33.                     inc(j);
  34.                     if j<>y then begin C[i1,j1]:=B[i,j];  inc(j1); end else continue; //если текущий столбец не равен вычёркиваемому - присвоить результирующему масссиву значение и увеличить счётчик результирующего. Если нет - следующая итерация
  35.                end;
  36.                inc(i1);
  37.           end
  38.           else continue;
  39.      end;
  40.      getArray:=C; //результат
  41. end;
  42.  
  43. function findDelta (B:array2; n:byte):real;  //поиск определителя матрицы
  44. const k=1; //строка,элементы которой будут множителями.
  45. var i:byte;
  46. rezult:real;
  47. begin
  48.      if n=1 then rezult:=B[1,1]; //
  49.      if n=2 then //если размерность 2 - получить определитель
  50.          rezult:=(B[1][1]*B[2][2])-(B[1][2]*B[2][1])
  51.      else         //если более 2х...
  52.      begin
  53.          for i:=1 to n do //по выбранной строке каждый элемент...
  54.          begin
  55.               //сумма:(-1)^(k+i)*элемент*минор... используется power (степень), функция уходит в рекурсию.
  56.               rezult:=rezult+(power(-1,k+i)*B[k,i]*findDelta(getArray(B,n,k,i),n-1));
  57.          end;
  58.      end;
  59. findDelta:=rezult; //результат
  60. end;
  61.  
  62. begin
  63.   //тело программы
  64.   writeln('Введите размерность матрицы');
  65.   readln(m);
  66.   writeln('Введите матрицу:');
  67.   for i:=1 to m do
  68.   begin
  69.        for j:=1 to m do
  70.        begin
  71.             write('A[',i,',',j,']= ');
  72.             readln(A[i,j]);
  73.        end;
  74.   writeln('------------');
  75.   end;
  76.   showArray(A,m);
  77.   writeln('delta=',findDelta(A,m):4:2);
  78. end.

Предлагаем модернизации кода, пишем функции для других операций над матрицами...
Я попробую покопать в сторону добавления примитивной логики в нахождение определителя (слишком много вычислений ложиться на процессор)...
Жду комментариев.
С уважением...

Что есть тип delta, и где Вы

Что есть тип delta, и где Вы используете Application?
Если n>2, то в функции findDelta изначально переменная rezult не инициализирована.
Зачем делать continue в конце тела цикла?
Определитель может быть вещественным, если все элементы матрицы целые?
В функции findDelta, если n=1 выполнится не только rezult:=B[1,1]; , но и то, что находится в строках 52-58. И рекурсия не остановится, пока стек не переполнится. n = 0, -1, -2, ...

Тема матриц

Боюсь, актуальна пока для немногих. Особенно по части подпрограмм.
Но мы вернёмся к ней позже.
А что касается конкретно приведённого выше кода - советую, Алексей, вникнуть в замечания Натальи.
И ещё - не злоупотребляйте оператором continue, а лучше вообще о нём забудьте!

Решение задачи Пила.

Условие: Необходимо исследовать массив элементов на признак образования пилы.

  1. program Pila;
  2.  
  3. const lim=10;
  4.   var
  5.   a:array[1..lim]of integer;
  6.   i,n:1..lim;
  7.   f:byte;//показывает какое ребро выходит из первой вершины (1-убывающее,2-возрастающее)
  8.   fp:boolean;
  9.  
  10. begin
  11.   writeln('Vvedite kolichestvo elementov massiva');
  12.   readln(n);
  13.   for i:=1 to n do begin write('a[',i,']=');readln(a[i]); end;
  14.   if (a[1]=a[2])or(n<3) then  writeln('Posledovatelnost ne obrazuet pilu') else
  15.   begin
  16.     if a[1]>a[2] then f:=1 else f:=2;
  17.     fp:=true;
  18.     for i:=2 to n-1 do
  19.         begin
  20.           if (f=1)and(((i mod 2=0)and(a[i]>=a[i+1]))or((i mod 3=0)and(a[i]<=a[i+1]))) then fp:=false;
  21.           if (f=2)and(((i mod 2=0)and(a[i]<=a[i+1]))or((i mod 3=0)and(a[i]>=a[i+1]))) then fp:=false;
  22.         end;
  23.     if fp=true then writeln('Posledovatelnost obrazuet pilu')else writeln('Posledovatelnost ne obrazuet pilu');
  24.   end;
  25.   read(n);
  26. end.

это вариант "тройками" как я поняла))

на компьютере прогнала работает))
а моя почему-то всегда выдает-" не пила",понятно что нужно исправить ошибку,но я даже не пойму где она...ПОМОГИТЕ кто-нибудь найти,а я постараюсь исправить))
program pila;
const lim=100;
var a:array[1..lim]of byte;
n,i:byte;
f:boolean;
begin
readln(n); f:=true;
for i:=1 to n do read(a[i]); {считываем массив}
if a[1]>a[2] then begin
for i:=1 to n-2 do
if (a[i+1]>=a[i])or(a[i+1]>=a[i+2]) then begin {если условие хоть одно истино то флаг становится ложью.условия беру специально те ,которые противоречащие условию}
f:=false;
break;
end
end
else begin
for i:=1 to n-2 do
if (a[i+1]<=a[i])or(a[i+1]<=a[i+2]) then begin{если условие хоть одно истино то флаг становится ложью.условия беру специально те ,которые противоречащие условию}
f:=false;
break;
end
end;
if f=false then write(' chislo- ne pila')
else write('chislo-pila');
readln
end.

ошибку нашла(спасибо Сереже)))

на втором шаге программа уже не работает. Как исправить пока не знаю,буду думать..

Что есть тип delta, и где Вы

Что есть тип delta, и где Вы используете Application?
- Писал на Lazarus'e под Linux... При написании сюда, удалил ни все служебные коды.
Если n>2, то в функции findDelta изначально переменная rezult не инициализирована.
Зачем делать continue в конце тела цикла?
Определитель может быть вещественным, если все элементы матрицы целые?
- Побочные ошибки. (результат корректирования на стадии разработки) Спасибо за указание.
В функции findDelta, если n=1 выполнится не только rezult:=B[1,1]; , но и то, что находится в строках 52-58. И рекурсия не остановится, пока стек не переполнится. n = 0, -1, -2, ...
- Да, это уже банальная невнимательность. Писал поздно, условие для матрицы одного элемента добавлял уже вне среды программирования.
Спасибо. Сейчас откорректирую.

program Project1; type    

  1. program Project1;
  2. type
  3.     array2=array[1..8, 1..8] of real;   //двумерный массив (тип для использования в подпрограммах)
  4. var
  5.   A:array2;   //массив
  6.   m,i,j:byte; //м-размерность массива
  7.  
  8. procedure showArray (B:array2; n:byte); //вывод массива в виде матрицы, н-размерность
  9. var i,j:byte;
  10. begin
  11.      for i:=1 to n do
  12.      begin
  13.           for j:=1 to n do
  14.           write(B[i,j]:2:2,' ');
  15.           writeln;
  16.      end;
  17. end;
  18.  
  19. function getArray (B:array2; n,x,y:byte):array2; //получения массива вычёркиванием х-строки и у-столбца
  20. var i,i1,j,j1:byte;
  21. C:array2;   //массив для результатов
  22. begin        //i,j - счётчики для В... i1,j1 - счётчики С
  23.      i:=0; i1:=1;
  24.      while i<n do //циклы следят за массивом В
  25.      begin
  26.           j1:=1;  j:=0; //инициализация переменных для столбцов на каждой итерации "строчного" цикла
  27.           inc(i);
  28.           if i<>x then   //если текущая строка не равна вычёркиваемой...
  29.           begin
  30.                while j<n do
  31.                begin
  32.                     inc(j);
  33.                     if j<>y then begin C[i1,j1]:=B[i,j];  inc(j1); end; //если текущий столбец не равен вычёркиваемому - присвоить результирующему масссиву значение и увеличить счётчик результирующего. Если нет - следующая итерация
  34.                end;
  35.                inc(i1);
  36.           end;
  37.      end;
  38.      getArray:=C; //результат
  39. end;
  40.  
  41. function findDelta (B:array2; n:byte):real;  //поиск определителя матрицы
  42. const k=1; //строка,элементы которой будут множителями.
  43. var i:byte;
  44. rezult:real;
  45. begin
  46.      result:=0;
  47.      if n=1 then rezult:=B[1][1] else
  48.      if n=2 then //если размерность 2 - получить определитель
  49.          rezult:=(B[1][1]*B[2][2])-(B[1][2]*B[2][1])
  50.      else         //если более 2х...
  51.      begin
  52.          for i:=1 to n do //по выбранной строке каждый элемент...
  53.          begin
  54.               //сумма:(-1)^(k+i)*элемент*минор... используется power (степень), функция уходит в рекурсию.
  55.               rezult:=rezult+(power(-1,k+i)*B[k,i]*findDelta(getArray(B,n,k,i),n-1));
  56.          end;
  57.      end;
  58. findDelta:=rezult; //результат
  59. end;
  60.  
  61. begin
  62.    //тело программы
  63.   writeln('Введите размерность матрицы');
  64.   readln(m);
  65.   writeln('Введите матрицу:');
  66.   for i:=1 to m do
  67.   begin
  68.        for j:=1 to m do
  69.        begin
  70.             write('A[',i,',',j,']= ');
  71.             readln(A[i,j]);
  72.        end;
  73.   writeln('------------');
  74.   end;
  75.   showArray(A,m);
  76.   writeln('delta=',findDelta(A,m):4:2);
  77. end.

Так должно работать..

Так должно работать..

все та же пила...

  1. program Project1;
  2.  
  3. {$APPTYPE CONSOLE}
  4.  
  5. uses
  6. SysUtils;
  7.  
  8. const lim=100;
  9. var a:array[1..lim]of byte;
  10. n,i:byte;
  11. f:boolean;
  12. begin
  13.   readln(n); f:=true;
  14.   for i:=1 to n do read(a[i]);
  15.   if a[1]>a[2] then begin
  16.    i:=1;
  17.    while i<=n-2 do
  18.     begin
  19.     if (a[i+1]>=a[i])or(a[i+1]>=a[i+2]) then f:=false;
  20.     i:=i+2;
  21.    end;
  22.    if(n mod 2=0)and(a[n]>=a[n-1])then f:=false;
  23.   end;
  24.  
  25.   if a[1]<a[2] then begin
  26.    i:=1;
  27.    while i<=n-2 do
  28.    begin
  29.     if (a[i+1]<=a[i])or(a[i+1]<=a[i+2]) then f:=false;
  30.     i:=i+2;
  31.    end;
  32.    if(n mod 2=0)and(a[n]<=a[n-1])then f:=false;
  33.   end;
  34.  
  35.   if a[1]=a[2] then f:=false;
  36.  
  37.   writeln(f);
  38.   readln(n);
  39.   end.
  40.        

Cерёжа, Оксана (+3), но я бы сделал короче ...

  1. program pila;
  2.   ... //описания
  3. begin  
  4.   readln(n);    fp:=true;
  5.   for i:=1 to n do read(a[i]);
  6.   if (n<3) then  writeln('No')
  7.   else begin
  8.       for i:=2 to n-1 do begin
  9.            if (a[i]-a[i-1])*(a[i]-a[i+1]) <= 0 then fp:=false;
  10.       end;
  11.       if fp then writeln('Yes')
  12.       else writeln('No');
  13.   end;
  14. end.

А для тех, кто не в теме, добавлю, что речь идёт о следующей задаче:
Назовём "пилой" массив целых чисел с поэлементно меняющимся направлением монотонности. Каждый элемент массива (кроме первого и последнего) является как бы зубцом пилы (локальным минимумом или максимумом). Например, пилами являются массивы 2,10,3,7,-1,4,0 или 6,3,6,1. Не является пилой, например, массив 2,5,5,1.
Написать программу проверяющую образует ли заданный массив "пилу".

ух ты,интересное решение))))

а кажется так просто и понятно,но до этого еще додуматься надо))

Пила

Я решил все-таки и свое решение опубликовать.

  1.  
  2. program pila;
  3.    const lim=50;
  4.    type mas=array[1..lim] of integer;
  5.    var a:mas; i:byte;
  6.        n,s,p:integer;
  7. begin
  8.    read(n);
  9.    for i := 1 to n do read(a[i]);
  10.    s:=0; p:=0;
  11.    for i := 1 to (n-2) do begin
  12.       if (a[i]<a[i+1]) and (a[i+1]>a[i+2]) then inc(s); //верхний зуб
  13.       if (a[i+1]<a[i+2]) and (a[i]>a[i+1]) then inc(p) //нижний зуб
  14.    end;
  15.    if (s+p)=(n-2) then writeln ('Pila') //в пиле каждый элемент кроме a[1] и a[n] - зуб
  16.       else writeln ('Ne pila');
  17.    readln
  18. end.

В.Ш., можно чуть-чуть

В.Ш., можно чуть-чуть улучшить Ваше решение?

  1.   program pila;
  2.      ... //описания
  3.   begin  
  4.      readln(n);    fp:=(n>=3);  
  5.      for i:=1 to n do read(a[i]);  
  6.      i:=2;
  7.      while fp and (i<n) do begin
  8.         fp :=((a[i]-a[i-1])*(a[i]-a[i+1]) <= 0);
  9.         Inc(i);
  10.      end;
  11.      if fp then writeln('Yes')
  12.      else writeln('No');
  13.   end.

Два замечания.

Саша, Вы размещаете код не только для меня, но и для других (т.е. для учебных целей). И, конечно, размещать в этом коде пояснения - не моя, а Ваша работа. Учтите это на будущее. А решение верное и, на мой взгляд, хорошее.

Наташа, боюсь, улучшение не удалось. Ошибку найдёте сами.

Ааа, поняла, в 8-й строчке

Ааа, поняла, в 8-й строчке надо условие наоборот поставить. Вместо "<=" - ">"

Не поможет, Наташа.

Не поможет, Наташа.

Не могу понять, что не так.

Не могу понять, что не так. Пробовала на разных примерах, работает. Заметила только то, что приведенный Вами пример 2,10,3,7,-1,0,4 не является пилой, т.к. последние 3 числа образуют возрастающую последовательность.

Каюсь, всё правильно,

Каюсь, всё правильно, реальное улучшение!
И последовательность подправил, спасибо.

Варианты

Как и обещал, дорешал задачу про все возможные варианты перестановок необходимого кол-ва цифр. Решение не супер, но рабочее. =)

  1. program variant;
  2.  
  3. {$APPTYPE CONSOLE}
  4.    var a,i,n,r,k,s,t,p:integer;
  5. begin
  6.    readln(n);
  7.    r:=1;
  8.    for i := 2 to n do begin
  9.       r:=r*10                //находим первое число, от которого будем искать
  10.    end;
  11.    for I := r to (r*10-1) do begin  //начинаем перебирать все числа с нужным кол-вом цифр
  12.       p:=0;
  13.       for k := 0 to n-1 do begin //проверяем кол-во и наличие нужных цифр
  14.          s:=i;
  15.          while s>0 do begin
  16.             a:=s mod 10;
  17.             if a=k then begin
  18.                inc(p);
  19.                break
  20.             end;
  21.             s:=s div 10
  22.          end;
  23.       end;
  24.       if p=n then writeln(i) //если число разных цифр в нужном диапозоне равно числу исходного кол-ва, то записываем его
  25.    end;
  26.    for I := (r div 10) to (r-1) do begin //проделываем то же самое, но теперь учитываем, что впереди ноль
  27.       p:=0;
  28.       for k := 1 to n-1 do begin
  29.          s:=i;
  30.          while s>0 do begin
  31.             a:=s mod 10;
  32.             if a=k then begin
  33.                inc(p);
  34.                break
  35.             end;
  36.             s:=s div 10
  37.          end;
  38.       end;
  39.       if p=(n-1) then writeln('0',i)
  40.    end;
  41.    readln
  42. end.

Принимается, Александр.

А вот решение несколько короче и быстрее:

  1. program perestanovki;
  2.      var i,n,k,p: integer;
  3.           a: array[-1..9] of Byte;
  4. begin
  5.    readln(n);
  6.    a[-1]:=0;  p:=n; //инициализация
  7.    for i:=0 to n-1 do a[i]:=i; //первая перестановка
  8.    While a[-1]=0 do begin //пока не возникнет перенос левее 0-разряда
  9.        If p=n then begin //вывод очередной перестановки
  10.              for i:= 0 to n-1 do write(a[i]); Writeln
  11.        End;
  12.        k:=n-1; // увеличение n-ичного числа на 1:
  13.        While a[k]=n-1 do begin
  14.            a[k]:=0; Dec(k)
  15.        End;
  16.        Inc(a[k]); // увеличили
  17.        p:=0; // проверка того, что получили перестановку:
  18.        For i:= 0 to n-1 do begin
  19.             For k:= 0 to n-1 do begin
  20.                  If a[k]=i then begin
  21.                       Inc(p); break
  22.                  End
  23.             End
  24.        End
  25.    End;//while
  26. End.

Формулировка задачи: По заданному 1< n< = 10 получить все перестановки чисел 0,1, ..., n-1.
Существуют и более эффективные алгоритмы решения этой задачи.

В.Шахамболетович

а почему в 12 шаге увеличение на один,если к:=n-1?непонятно

Оксана, код увеличения на

Оксана, код увеличения на самом деле занимает с 12 по 16 строчки и состоит в следующем.
Если, например, n=5 и мы уже имеем число 10244, то следующим (на 1 большим) будет 10300.
А как оно получается? Прибавлением 1 к 10244 в 5-ричной системе счисления. Все цифры равные 4
(т.е. n-1) справа налево, начиная с последнего, т.е. с n-1-го разряда (поэтому k:=n-1) заменяем на нули, а 2 увеличиваем на 1.

аааа,вот теперь все понятно))))

спасибо за объяснение)))))

Можно избежать вложенных

Можно избежать вложенных циклов 18-24, если проверку того, что все цифры (от 0 до n-1) присутствуют в числе производить вычёркиванием найденных уже цифр следующим образом. Заводим булевый массив b[0], ..., b[n-1] и инициализируем его значениями false.
Далее, в цикле, если при просмотре массива a обнаруживается, например 2, то элементу b[2] (если он всё ещё false) присваиваем true. Если a - перестановка (и только в этом случае), в конце цикла все элементы b будут установлены в true.
Устранение кратных (т.е. вложенных) циклов является важным фактором ускорения программы - в этом смысл описанной модификации.

Попробуйте реализовать эту идею!

Слияние двух упорядоченных массивов

  1. Program slianie;
  2. const n=10;m=5;
  3. var a:array[1..n]of integer;
  4.     b:array[1..m]of integer;
  5.     c:array[1..n+m]of integer;
  6.     i,j,k:integer;
  7. begin
  8.  writeln('vvedite massiv a');
  9.  for i:=1 to n do read(a[i]);
  10.  writeln;
  11.  writeln('vvedite massiv b');
  12.  for j:=1 to m do read(b[j]);
  13.  writeln;
  14.  i:=1;j:=1;k:=1;
  15.  while k<=n+m do begin
  16.   if(j>m)and(i<=n)then begin
  17.     c[k]:=a[i];
  18.     Inc(i);
  19.   end;
  20.   if (i>n)and(j<=m)then begin
  21.     c[k]:=b[j];
  22.     inc(j);
  23.   end;
  24.   if(i<=n)and(j<=m)then begin
  25.     if a[i]<b[j]then begin
  26.        c[k]:=a[i];
  27.        Inc(j);
  28.     end else begin
  29.           c[k]:=b[j];
  30.           inc(j);
  31.         end;
  32.   end;
  33.         write(c[k],' ');
  34.         Inc(k);
  35.   end;
  36.    
  37.   readln
  38. end.

Однокурсники помогите

Просьба к однокурсникам и другим студентам ФаМиКоНа Проверьте пожалуйста на наличие ошибок:
Значит задача программы в следующем вычислить значение e в степени (далее ^) x. Выводить надо значиние членов ряда е^x=1+x+x^2/2!+x^3/3!.... начиная с 5-го члена до заданного k, т.е. выводить значение х^6/6! потом x^7 и так далее.

  1. Program my_exp;
  2. var expon,x,p:Real; i,n,k:Integer;
  3. begin
  4. readln(x,k);
  5. expon:=0;
  6. p:=1; //значение первого члена
  7. i:=0;
  8. for n:= 2 to 4 do begin   //вычисляем 2-ой, 3-й и 4-й член, чтобы начать работу с 5-го члена
  9.   expon:=expon+a; //в данном случае необязательная строчка, т.к. не влияет на значение членов
  10.   Inc(i);
  11.   a:=a*x/i
  12. end;
  13. for n:=5 to k do begin    //вычисляем значение е^x, начиная с пятого члена, до заданного k, выводя значение последующих членов
  14.   expon:=expon+a;  //в данном случае необязательная строчка, т.к. не влияет на значение членов
  15.   Inc(i);
  16.   a:=a*x/i;
  17.   writeln(a);
  18. end;
  19. end.

Переменная а не объявлена и

Переменная а не объявлена и не инициализирована.
В строках 9 и 14 и переменной p нет смысла, если они нигде не используются.
И можно обойтись без переменной i, если 1-й цикл сделать от 1 до 3-х, а второй от 4-х и до k-1. Нужно только подобрать соответствующее начальное значение а.

Пробывал решать эту задачу,

Пробывал решать эту задачу, но не получается - есть ошибки. Хотелось бы разобрать эту задачу вместе.

1. program pr_1;
2. var m, n, p:integer;
3. begin
4. read(m,n);
5. if n mod 2=0 then begin
6. p:=sqr(m)*n;
7. writeln('y=',p);
8. end
9. else begin
10. p:=sqr(m)*(n-1)*m;
11. writeln('y=',p);
12. end;
13. end.

Забыл поменять

Переменные взял уже из готового шаблона, а основную часть дописывал сам и, увлекшись основной частью, забыл про то, что переменные не совпадают. Спасибо, Наташа, за правку моей программы. Что касаеться использование переменой i, то можно ли рассматривать программу с ней как вариант решения? Куда относить эту i к типу Real или Integer, ведь у нас переменная х типа Real делиться на i типа Integer.

  1. Program my_exp;
  2. var expon,x,а:Real; i,n,k:Integer;
  3. begin
  4. readln(x,k);
  5. expon:=0;
  6. а:=1; //значение первого члена
  7. i:=0;
  8. for n:= 2 to 4 do begin   //вычисляем 2-ой, 3-й и 4-й член, чтобы начать работу с 5-го члена
  9.   Inc(i);
  10.   a:=a*x/i
  11. end;
  12. for n:=5 to k do begin    //вычисляем значение е^x, начиная с пятого члена, до заданного k, выводя значение последующих членов
  13.    Inc(i);
  14.   a:=a*x/i;
  15.   writeln(a);
  16. end;
  17. end.

Вот решение с исправленой переменной и без нетребующегося вычисления е^x. Верна ли программа синтаксически и в вычислениях?

Транспонирование матрицы

  1. program Transp;
  2.  const lim = 50;
  3.  type MTRX = array[1..lim,1..lim] of integer;
  4.  var a:MTRX, m,n,max,i,j:1..lim; k:integer;
  5. begin
  6.  read(m,n);
  7.  for i:=1 to m do begin
  8.   for j:=1 to n do begin
  9.    write ('a[',i,'][',j,']=');
  10.    read(a[i,j])
  11.   end
  12.  end;
  13.  max:=n;
  14.  if m>n then max:=m;
  15.  for i:=1 to max do begin
  16.   for j:=i to max do begin
  17.    k:=a[i,j]; a[i,j]:=a[j,i]; a[j,i]:=k
  18.   end
  19.  end;
  20.  for i:=1 to n do begin
  21.   writeln;
  22.   for j:=1 to m do begin
  23.    write(a[i,j])
  24.   end
  25.  end
  26. end.

Транспонирование

Опередил на час :( Ну врочем я собирался доделать для квадратной матрицы и с использованием другой матрицы. Кстате, Дима, у тебя хорошая программа - работает как для квадратных так и для остальных матриц. (маленький недочет в 4 строке после объявления переменной "a" типа MTRX поставил запятую)
Мой вариант траспонирования с помощью другой матрицы. Практически схож с вариантом Димы, для наглядности использовал те же переменные и операции что и Дима. Так же добавил еще один writeln в цикле вывода и пробел перед элементами для красоты.

  1. program TranspAnyVariant;
  2.  const lim = 50;
  3.  type MTRX = array[1..lim,1..lim] of integer;
  4.  var a,b:MTRX; m,n,max,i,j:1..lim; {берем переменную "b" такого же типа как и "a", переменная "k" не понадобиться}
  5. begin
  6.  read(m,n);
  7.  for i:=1 to m do begin
  8.   for j:=1 to n do begin
  9.    write ('a[',i,'][',j,']=');
  10.    read(a[i,j])
  11.   end
  12.  end;
  13.  max:=n;
  14.  if m>n then max:=m;
  15.  for i:=1 to max do begin
  16.   for j:=i to max do begin
  17.    b[j,i]:=a[i,j];  b[i,j]:=a[j,i];  {отличие от предыдущего варианта в цикле транспонирования}
  18.   end
  19.  end;
  20.  for i:=1 to n do begin
  21.   writeln;
  22.   writeln;                      
  23.   for j:=1 to m do begin
  24.    write(b[i,j],' ')
  25.   end
  26.  end
  27. end.

Синтаксически то она верная.

Синтаксически то она верная. И выводит на экран то, что надо. Только слишком много лишнего.

  1. program MyExp;
  2. var
  3.    x, a: Real;
  4.    i, k: Integer;
  5. begin
  6.    Readln(x, k);
  7.    a := 1.0; //Первый член ряда
  8.    for i := 1 to 3 do
  9.       a := a*x/i; //Вычисление со 2-ого по 4-й член ряда
  10.    for i := 4 to (k-1) do begin
  11.       a := a*x/i; //Вычисление с 5-ого по k-й член ряда
  12.       Writeln(a);
  13.    end;
  14. end.

По транспонированию матрицы

Решение Молчанова Д. принимается, хотя с логической точки зрения его нельзя признать корректным (возможно манипулирование логически не существующими элементами матрицы - это цена за попытку обобщения условия так, чтобы оно охватывало и не обязательно квадратные матрицы ).
Другим недостатком этого решения является отсутствие каких-либо объяснений (в частности, связанных с переменной границей внутреннего цикла). Если честно, мне малоинтересны решения, которые пишутся только для меня.
Итог - +2.
Решение Фирсова Е.. дублирует решение Молчанова, существенно его ухудшая. Рассматривая задачи связанные с обработкой массивов (сортировки, поиск, векторные и матричные вычисления и т.п.) мы практически никогда не идём ухудшение эффктивности по расходу памяти за счёт резервирования дополнительных рабочих массивов. Исключение могут составлять те редкие и специально оговариваемые случаи, когда такие "жертвы" особо оправданы или попросту неизбежны.

Спасибо большое

Спасибо большое Наташа, за разъяснение задачи. Странно почему Валерий Шахамболетович отказался проверять ее.
Что касаеться моего варианта транспонирования матрицы, сделал специально через другой массив, так как в будущем нам не раз придеться сталкиваться с решением нескольких массивов и данный пример может послужить опорой. Такой способ транспонирования очень удобно использовать , если нам требуеться вывести заданную матрицу, а после транспонированную, либо совершать действия одновременно с обоими типами матриц.

По задаче об экспоненте X

Речь идёт о задании и, соответственно, о задаче, варианты решения которой опубликованы выше Фирсовым Е. и Стаценко Н.
Поскольку это частное задание Фирсову Е. так и не было им до конца понято (но зато вынесено на сайт в искажённой и довольно бессмысленной форме, на которую "повелась" Наташа и которую я не считал возможным обсуждать), вынужден уточнить, уже для всех, в виде бонусной задачи, в чём же эта задача всё-таки состоит.

Вам предлагается выполнить следующее маленькое исследование. Как мы знаем, для вычисления exp(x) в Паскале есть по крайней мере 3 возможности:
1. Зная о разложении этой ф-ции в бесконечный степенной ряд, вычислить её при заданном значении X с заданной степенью точности Eps (это мы делали на лекции; там же мы говорили об условии сходимости ряда - |X|<1 ). Вводить нужно будет X и Eps.
2. Опять же, на основе разложения этой ф-ции в бесконечный степенной ряд, вычислить её при данном значении X, но с учётом только первых N членов ряда (наряду с X нам теперь нужно будет задавать не Eps, а N);
3. Воспользоваться соответствующей стандартной функцией (тогда, при заданном X, мы получим ответ сразу, но без всякого контроля над точностью с нашей стороны);

Во втором и третьем случаях, обеспечиваемая вычислениями точность (число верных знаков после запятой) нам неизвестна. Относительно (2) можно только сказать, что чем больше N, тем теоретически больше и точность.

Так вот, задача состоит в том, чтобы придумать программу, которая в удобной и наглядной форме позволила бы экспериментально проверить последнее утверждение, за счёт сравнения значений получаемых по методам (2) и (3).
Как побочный результат таких экспериментов, следует оценить (выяснить хотя бы приблизительно) ту точность, которую обеспечивает стандартная функция exp(X).

Да... Вот по этому всегда

Да... Вот по этому всегда нужно публиковать условие в таком виде, в каком оно было изначально...

Exp(x)

Вы мне дали задание немного другое, там надо было выводить более подробнее, я по невнимательности забыл что |x|<1 должен быть, поэтому вы мне задали второе задание более упрощеное, которое я написал тут чтобы спросить у Наташи правильно ли я его сделал, так как вы отказались проверять его.

Моя задача

Насколько я понял что нужно делать:

  1. program e_v_stepeni_x;
  2. var expon,a,x:Real; n,k,i:Byte;
  3. begin
  4. write('vvedite stepen x='); readln(x);
  5. write('vvedite granitsu dlja n=5..'); readln(k);
  6. expon:=0;
  7. a:=1;
  8. i:=0;
  9. for n:= 1 to 3 do begin   //вычисляем первые 4 члена, для начала работы с 5-го члена
  10.   expon:=expon+a; Inc(i);
  11.   a:=a*x/i
  12. end;
  13. writeln('obshee zna4enie exp(x)=',exp(x):0:20);
  14. for n:=5 to k do begin     //вычисляем значение е^x, начиная с пятого члена, до заданного k
  15.   expon:=expon+a; Inc(i);
  16.   a:=a*x/i;
  17.   writeln('dlja n=',n,' chlennov zna4enie exponenti=',expon:0:20,' zna4enie ',n,'-ogo chlena =',a:0:20);  //если значиние текущего члена меньше eps останавливаем вычисление и выводим номер члена
  18. end;
  19. readln
  20. end.

Ещё одна бонусная задача

Как мы знаем, операция x^n (возведение x в целую неотрицательную степень) в Паскале отсутствует. Имеются по меньшей мере две возможности её реализации:
1. Выразить через стандартные ф-ции. Идея следующая. Нам нужно найти y=x^n. Прологарифмировав обе части по натуральному основанию, получим ln(y) = n*ln(x). Теперь, потенцируя, получаем exp( ln(y)) = exp(n*ln(x)) или, окончательно, у = exp(n*ln(x)) .
Сразу же оговоримся, что хотя этот путь наиболее лёгок для программиcта, он и наиболее неэффективен по времени (напомню, встроенные ф-ции exp(x) и ln(x) используют в cвоей внутренней реализации разложение в степенной ряд, а значит внутренние циклические вычисления в медленной арифметике плавающей точки). К тому же, дополнительных забот требует случай x<=0.

2. Реализовать программно. Простой алгоритм, основанный на умножении очевиден и состоит в следующем цикле на n повторений:

  1. ...
  2.    y:=1; For i:=1 to n do y:=y*x;
  3. ...

Но можно ли придумать более эффективный алгоритм чем (2), где в общем случае, число повторений цикла было бы значительно меньше? Оказывается, можно.
Идея в следующем. Если n -чётное (т.е. n=2k), то вместо x^(2k) мы вычислим (x^2)^k. А если нечётное, то вместо x^(2k+1) мы вычислим x(x^(2k))= x(x^2)^k. Тот же принцип мы применим к вычислению (x^2)^k и т.д. Например, вместо 2^10 вычислим 4^5, но дальше 4^5 будем вычислять как 4*(16)^2 и т.д.

Так вот, бонусная задача: Программно реализовать выше приведённую идею эффективного вычисления функции y=x^n.

P.S. Кстати, ранее несколькими постами назад приведённая попытка решения этой задачи Сайгановым Г., очевидно неудачна, т.к даже не содержит цикла (без которого, конечно же не обойтись).

Шейкерная сортировка

Вот ссылка на код и комментарии к нему