Про Эрмитаж

Задачи читателей. День первый. «Про Эрмитаж».

Здравствуйте, дорогие читатели! Сегодня к нам в редакцию поступил вопрос по форме обратной связи. Хотя мы с вами еще не изучали эту тему, мы не можем проигнорировать спросившего. К тому же мы еще и социально-активный сайт. Так что условие и решение под катом.


Поступившее сообщение:

Здравствуйте,помогите пожалуйста с решением задачи. Решить нужно с помощью циклов for,while.

Задача «Про Эрмитаж»: 

1 февраля в Эрмитаже открылась выставка. Цена билета x руб. Сколько дней потребуется Эрмитажу,чтобы собрать выручку с билетов y руб. Известно,что в первый день на выставку пришло A людей, а в каждый последующий день выставку посещало на B людей меньше. 

И тут перед нами возник вопрос:  каким способом решать? С помощью for или с помощью while? Недолго думая, мы записали решение сразу двумя способами.

Для начала давайте определимся, какие знания нам потребуются для решения данной задачи. В идеале: это знание циклов, ветвлений, меток и оператора break.

Итак, начнем.

Способ первый. Решение задачи «Про Эрмитаж» с помощью цикла while.

label 1; {метка}

var
  x, y, a, b, k, count: integer;

begin

//ВВОД ДАННЫХ

  write('Введите цену билета: ');
  readln(x);
  write('Введите размер выручки: ');
  readln(y);
  write('Введите количество людей A: ');
  readln(a);
  write('Введите количество людей B: ');
  readln(b);

// ОСНОВНАЯ ПРОГРАММА

  if a > 0 then begin {Проверяем, равняется ли а нулю. Понятно, что если а = 0, то решать задачу дальше нет смысла.}
    k := a * x;
    count := 1; {Задаем начальное значение count, не забывайте, что в PascalABC.NET значения переменных обнуляются по умолчанию.}
    while k < y do begin {пока заработок меньше выручки, выполняем}      
      if a - b > 0 then {проверяем, не закончились ли посетители}
      begin
        a := a - b;   {Уменьшаем количество людей}
        k := k + a * x;   {Собираем прибыль}
        count := count + 1; {Увеличиваем счетчик}
      end 
      else 
      begin
        write('не успеют!');
        goto 1; {оператор безусловного перехода}
      end;
    end;
  end;

//ВЫВОД

  writeln('Ответ: ', count);
  1: {мы переместились в конец}
end.

Если вы внимательно читали программу, то вы знаете, что ее можно сократить, если принять за данность, что входные значения адекватны. Это будет выглядеть так:

 

var
  x, y, a, b, k, count: integer;

begin

  //ВВОД ДАННЫХ

  write('Введите цену билета: ');
  readln(x);
  write('Введите размер выручки: ');
  readln(y);
  write('Введите количество людей A: ');
  readln(a);
  write('Введите количество людей B: ');
  readln(b);

 //ОСНОВНАЯ ПРОГРАММА

  k := a * x;
  count := 1;
  while k < y do
  begin
    a := a - b;
    k := k + a * x;
    count := count + 1;
  end;

 //ВЫВОД

  writeln('Ответ: ', count);
end.

Способ второй. Решение  задачи «Про Эрмитаж» с помощью цикла for.

 

label 1; {опять эта метка!}

var
  x, y, a, b, k, count: integer;

begin

// ВВОД ДАННЫХ
  write('Введите цену билета: ');
  readln(x);
  write('Введите размер выручки: ');
  readln(y);
  write('Введите количество людей A: ');
  readln(a);
  write('Введите количество людей B: ');
  readln(b);

//ОСНОВНАЯ ПРОГРАММА
  if a > 0 then {проверка}
  begin
    k := a * x;
    for count := 1 to MaxInt do {Так как мы не знаем сколько дней будет длится собирание денег, используем встроенную переменную MaxInt.ЕЕ значение 200000000 и больше. }
      if k >= y then break else {если мы собрали требуемые деньги, прерываем цикл с помощью break. }
      begin
        if a - b > 0 then {опять проверка.}
        begin
          a := a - b; {считаем}
          k := k + a * x; {count явеличивается автоматом}
        end
        else 
        begin
          write('Не успеют.');
          goto 1; {оператор безусловного перехода.}
        end;
      end;
  end;
  writeln('Ответ: ', count);
  1: {Переместились}
end.

Многие знают, что использовать goto — плохой стиль, поэтому давайте создадим альтернативу. Используем переменную-флаг.

var
  x, y, a, b, k, count: integer;
  flag: boolean; {наша переменная-флаг}

begin
//ВВОД ДАННЫХ
  write('Введите цену билета: ');
  readln(x);
  write('Введите размер выручки: ');
  readln(y);
  write('Введите количество людей A: ');
  readln(a);
  write('Введите количество людей B: ');
  readln(b);

//ОСНОВНАЯ ПРОГРАММА

  flag := true; {присваиваем первое значение}
  if a > 0 then {проверка}
  begin
    k := a * x;
    for count := 1 to MaxInt do 
    begin
      if flag = false then break; {Если люди уже ушли в минус -прекращаем бессмысленную трату ресурсов компьютера}
      if k >= y then break else 
      begin
        if a - b > 0 then 
        begin
          a := a - b;
          k := k + a * x;
        end
        else flag := false; {присваиваем второе значение}
      end;
    end;
  end;
  if flag then writeln('Ответ: ', count) else writeln('Не хватает'); {Выбор}
end.

На сегодня все! Не забывайте кликать по кнопочкам и подписываться на наш сайт.

  • Александр

    Почему у вас данная задача с циклами идет перед уроком с этими самыми циклами? Т.е. выходит, что циклы мы еще не изучили, а задачу уже решаем?