· ключевая тема этого задания ЕГЭ – использование вложенных условных операторов, причем в тексте задания фрагмент программы обычно записан без отступов «лесенкой» или с неправильными отступами, например, так:
Чтобы разобраться с работой этих программ, нужно определить, к какому из условных операторов if относится часть else; для этого используют такое правило: «любой else относится к ближайшему if». Рассмотрим фрагмент слева, в нем перед else стоит end, поэтому для него нужно найти соответствующий ему begin; таким образом определяем, что else относится к первому (внешнему) условному оператору. В правом фрагменте перед else нет end, поэтому он относится к ближайшему по тексту внутреннему условному оператору. Блок-схемы для двух фрагментов показаны ниже, желтым цветом выделен «переехавший» блок:
· в условных операторах можно использовать сложные условия, которые строятся из простых отношений (<, <=, >, >=, =, <>) с помощью логических операций not («НЕ», отрицание), and («И», одновременное выполнение двух условий) и or («ИЛИ», выполнение хотя бы одного из двух условий) · в сложном условии сначала выполняются действия в скобках, потом – not, затем – and, затем – or и, наконец, отношения; · поскольку отношения в Паскале имеют низший приоритет, в сложном условии их приходится брать в скобки:
· в приведенном выше примере сначала определяются результаты сравнения (выражения в скобках), затем выполняется операция and («И»), а затем – or («ИЛИ») Пример задания: На обработку поступает последовательность из четырёх неотрицательных целых чисел (некоторые числа могут быть одинаковыми). Нужно написать программу, которая выводит на экран количество нечётных чисел в исходной последовательности и максимальное нечётное число. Если нечётных чисел нет, требуется на экран вывести «NO». Известно, что вводимые числа не превышают 1000. Программист написал программу неправильно. Вот она: const n = 4; var i, x: integer; var maximum, count: integer; Begin count := 0; maximum := 999; for i := 1 to n do begin read(x); if x mod 2 <> 0 then begin count := count + 1; if x > maximum then maximum := i End end; if count > 0 then begin writeln(count); Writeln(maximum) End Else writeln('NO') End. Последовательно выполните следующее. 1. Напишите, что выведет эта программа при вводе последовательности: 2 9 4 3 2. Приведите пример такой последовательности, содержащей хотя бы одно нечётное число, что, несмотря на ошибки, программа печатает правильный ответ. 3. Найдите все ошибки в этой программе (их может быть одна или несколько). Известно, что каждая ошибка затрагивает только одну строку и может быть исправлена без изменения других строк. Для каждой ошибки: 1) выпишите строку, в которой сделана ошибка; 2) укажите, как исправить ошибку, т.е приведите правильный вариант строки. Обратите внимание, что требуется найти ошибки в имеющейся программе, а не написать свою, возможно, использующую другой алгоритм решения. Исправление ошибки должно затрагивать только строку, в которой находится ошибка. Решение: 1) обратим внимание на две строки в начале программы, которые начинаются с ключевого слова var: это не ошибка, такое повторение, действительно, допустимо в языке Паскаль; возможно, это была одна из ловушек разработчиков КИМ, которую они применили на реальном ЕГЭ-2014 2) теперь выполним программу для заданной последовательности 2 9 4 3, записывая все изменения переменных в таблицу:
3) при ручной прокрутке программы мы увидели, что она правильно подсчитала количество нечётных чисел во входной последовательности, но неверно определила максимум: значение переменной maximum, которое было выведено на экран, осталось равным начальному значению 999, так как все остальные нечётные числа были меньше этого начального значения; поэтому ответ на п. 1 задания должен быть таким: 1) Программа выведет числа 2 и 999. 4) поскольку все числа по условию неотрицательны и не превышают 1000, программа всегда будет выдавать 999 вместо максимального нечётного числа; в то же время мы выяснили, что количество нечётных чисел в последовательности считается правильно; поэтому любая последовательность, содержащая 999, будет обрабатываться правильно 5) таким образом, правильный ответ на п. 2 должен быть таким: 2) Программа работает правильно для последовательности: 2 9 3 999. 6) теперь будем искать ошибки; как уже отмечалось, повторное использование ключевого слова var допустимо и указывать это в качестве ошибки нельзя! 7) как следует из результатов ручной прокрутки программы, во многих случаях она выдаёт неверный результат из-за того, что неверно задано начальное значение переменной maximum: оно должно быть меньше, чем любой возможный результат; 8) наименьшее нечётное неотрицательное число – это 1, поэтому можно принять в качестве начального значения maximum любое число, меньшее единицы (на самом деле, программа будет правильно работать и для 1), например: 3) Ошибка 1. maximum:=999; Исправление: maximum:=0; 9) если теперь (с исправленной первой ошибкой) сделать ручную прокрутку программы, то мы увидим, что на последовательности 2 9 4 3 она выдает сначала 2, а потом – 4, то есть, значение максимума вычисляется опять наверно; 10) откуда появится число 4 в переменной maximum? оно будет записана в результате выполнения оператора if x > maximum then maximum:=i, который записывает в переменную maximum не значение полученного числа (x), а его номер (i); таким образом, мы нашли вторую ошибку: Ошибка 2. if x > maximum then maximum:=i Исправление: if x > maximum then maximum:=x Ещё пример задания: Требовалось написать программу, которая вводит с клавиатуры натуральное число N, не превышающее 109, и выводит сумму чётных цифр в десятичной записи этого числа или 0, если чётных цифр нет. Программист торопился и написал программу неправильно. Вот она: var N: longint; s: integer; Begin Readln(N); (1) s := 0; (2) while N > 1 do begin (3) if N mod 2 = 0 then begin (4) s := N mod 10; (5) End; (6) N := N div 10; (7) End; (8) Write(s); (9) End. Последовательно выполните следующее. 1. Напишите, что выведет эта программа при вводе числа 1984. 2. Приведите пример числа, при вводе которого программа выдаст верный ответ. 3. Найдите в программе все ошибки (их может быть одна или несколько). Для каждой ошибки выпишите строку, в которой она допущена, и приведите эту же строку в исправленном виде. Обратите внимание: вам нужно исправить приведённую программу, а не написать свою. Вы можете только заменять ошибочные строки, но не можете удалять строки или добавлять новые. Заменять следует только ошибочные строки: за исправления, внесённые в строки, не содержащие ошибок, баллы будут снижаться. Решение: 11) начнем с того, что разберёмся в условии задачи: ограничение N < 109 введено для того, чтобы число поместилось в 4-байтовую переменную целого типа, для совместимости со всеми трансляторами Паскаля соответствующая переменная объявлена как longint 12) теперь разберём программу; строка (1) – это ввод исходного числа; очевидно, что переменная s – это результат, поскольку именно она выводится в строке (9) 13) в строке (2) переменная s обнуляется, это естественно при накоплении суммы 14) строки (3)-(8) – это цикл, который выполняется пока N > 1; на каждом шаге цикла N делится на 10 нацело, то есть, из десятичной записи числа отбрасывается последняя цифра (строка (7)); такой цикл используется для того, чтобы перебрать все цифры числа, но обычно ставят условие «N > 0», поскольку в приведенном варианте цикл остановится при N = 1; однако в данном случае это не влияет на результат, поскольку по условию нас интересуют только чётные цифры, а 1 – нечётная 15) в строке (4) проверяется чётность числа (и одновременно чётность его последней цифры!), если число чётное, в строке (5) в переменную s записывается остаток от деления числа на 10, то есть последняя цифра десятичной записи этого числа 16) таким образом, после выполнения цикла будет выведена последняя рассмотренная цифра, для которой сработает условие в строке (4) 17) поскольку цифры перебираются с конца, выводится первая чётная цифра в записи числа 18) начнём выполнять задание: 1. При вводе числа 1984 будет выведено число 8 – значение первой чётной цифры числа. 19) когда программа выдаст верный ответ? очевидно, что тогда, когда сумма чётных цифр и значение первой чётной цифры совпадают; это возможно, если в числе · нет чётных цифр (сумма останется равной 0) · все чётные цифры – нули · одна чётная цифра · одна ненулевая чётная цифра, а нули стоят после неё (нули не меняют суммы!) 2. Программа выдаст правильный ответ для N = 1981. 20) как исправить программы? очевидно, нужно, чтобы она считала сумму чётных цифр, то есть, получив очередную чётную цифру, нужно добавить её к «старому» значению переменно s, изменив строку (5) так: s := s + N mod 10; (5) 3. Ошибка допущена в строке s := N mod 10; Эта строка должна в правильной программе выглядеть так s := s + N mod 10; Ещё пример задания: Требовалось написать программу, которая вводит с клавиатуры координаты точки на плоскости (x,y – действительные числа) и определяет принадлежность точки заштрихованной области, включая ее границы. Программист торопился и написал программу неправильно. Вот она: var x,y: real; Begin readln(x,y); if y <= 1 then if x >= 0 then if y >= sin(x) then Write('принадлежит') else write('не принадлежит') End. Последовательно выполните следующее: 1) Приведите пример таких чисел x, y, при которых программа неверно решает поставленную задачу. 2) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы. (Это можно сделать несколькими способами, поэтому можно указать любой способ доработки исходной программы) . Решение: 1) сначала лучше отложить в сторону программу и попытаться написать условие, которым должны отвечать точки, попавшие в выделенную область 2) заштрихованная область ограничена по координате , она находится · справа от оси , что равносильно условию (с учетом границы здесь и далее получаем нестрогие неравенства) · слева от первого максимума функции ; из математики мы знаем, что эта функция достигает максимума при , поэтому получаем второе условие 3) заштрихованная область ограничена с двух сторон по координате : она находится · ниже линии , откуда следует третье условие · выше линии , что дает четвертое условие 4) итак, точка находится в заданной области, если все эти четыре условия выполняются одновременно; можно предположить, что в программе нужно использовать четыре вложенных условных оператора или один условный оператор, в котором четыре простых условия (отношения , , и ) связаны с помощью логической операции and («И», одновременное выполнение всех условий) 5) теперь смотрим на программу: здесь три (а не четыре!) вложенных условных оператора с простыми отношениями, поэтому явно какое-то условие не учтено; легко найти, что «забыли» условие 6) оператор write('принадлежит') помещен внутрь всех трех условных операторов, то есть, он выполнится тогда, когда три (а не четыре!) условия истинны; 7) отметим на рисунке область, где выполняются все нужные условия, кроме (красная зона); 8) для всех точек, которые находятся в «красной» зоне программа выдаст сообщение «принадлежит», хотя в самом деле эти точки не принадлежит заданной области; одна из таких точек имеет координаты 9) теперь выясним, когда программа выдает сообщение «не принадлежит» if y <= 1 then if x >= 0 then if y >= sin(x) then Write('принадлежит')
12 Не нашли, что искали? Воспользуйтесь поиском по сайту: ©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.
|