Раздел "Программирование" единого государственного экзамена

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

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 30.01.2011
Размер файла 137,5 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Министерство образования Удмуртской Республики

Государственное образовательное учреждение

высшего профессионального образования

«Глазовский государственный педагогический институт»

филиал в г. Ижевске

Курсовая работа

Задачи по разделу "Программирование” единого государственного экзамена

Выполнил:

студентка 3 курса з/о «Информатика»

Волкова Татьяна Михайловна

Руководитель: Уткина О.Н.

Ижевск

2010

Введение

Подготовка к ЕГЭ по информатике стала актуальной с введением экзамена по информатике по выбору при окончании средней школы и введением в некоторых ВУЗах, включая и гуманитарные, вступительных экзаменов по информатике.

Тема «Программирование» - один из разделов, изучаемых в рамках учебной дисциплины «Информатика и ИКТ» на профильном уровне.

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

Цель: комплексное, системное изучение задач раздела «Программирование» ЕГЭ 2006-2009 гг.

Достижение поставленной цели требует постановки и решения следующих задач:

1. Провести теоретический анализ задач раздела «Программирование» ЕГЭ;

2. Разработать методические рекомендации при подготовке к ЕГЭ для учителей и учащихся.

Задачи раздела «Программирование» единого государственного экзамена, их решения

Тема « Оператор присваивания в языке программирования»

2006 год

Определите значение целочисленных переменных a и b после выполнения фрагмента программы:

Бейсик

Паскаль

Алгоритмический

a=2468 b=(a MOD 1000)*10

a=a\1000+b

'\ и MOD -- операции, вычисляющие результат деления нацело первого аргумента на второй и остаток от деления соответственно

a:=2468;

b:=(a mod 1000)*10;

a:=a div 1000+b;

{div и mod -- операции, вычисляющие результат деления нацело первого аргумента на второй и остаток от деления соответственно}

a:=2468

b:=mod(a, 1000)*10

a:=div(a, 1000)+b |div и mod -- функции, вычисляющие результат деления нацело первого аргумента на второй и остаток от деления соответственно|

1)

a = 22, b = 20

2)

a = 4682, b = 4680

3)

a = 8246, b = 246

4)

a = 470, b = 468

Решение:

a:=2468;

b:=(a mod 1000)*10;

a:=a div 1000+b;

b:=(2468 mod 1000)*10= 4680;

a:=2468 div 1000+4680=4682;

a:=4682, b:= 4680.

Верный ответ: 2.

2007 год

Определите значение целочисленных переменных a и b после выполнения фрагмента программы:

Бейсик

Паскаль

Алгоритмический

a = 1819 b = (a \ 100) * 10 + 9 a = (10*b - a) MOD 100 '\ и MOD - операции, вычисляющие результат деления нацело первого аргумента на второй и остаток от деления соответственно

a:= 1819; b:= (a div 100)*10+9; a:= (10*b-a) mod 100; {div и mod - операции, вычисляющие результат деления нацело первого аргумента на второй и остаток от деления соответственно}

a:= 1819 b:= div(a,100)*10+9 a:= mod(10*b - a,100) |div и mod - функции, вычисляющие результат деления нацело первого аргумента на второй и остаток от деления соответственно|

1)

a = 81, b = 199

2)

a = 81, b = 189

3)

a = 71, b = 199

4)

a = 71, b = 189

Решение:

a:=1819;

b:=(a div100)*10+9;

a:=(10*b-a) mod 100;

b:=(1819 div 100)*10+9=189;

a:=(10*189-1819) mod 100=71 mod 100=71;

а:=71, b:=189.

Верный ответ: 4

2008 год

Определите значение целочисленных переменных a и b после выполнения фрагмента программы:

Бейсик

Паскаль

Алгоритмический

a = 3 + 8 * 4 b = (a \ 10) + 14 a = (b MOD 10) + 2 '\ и MOD - операции, вычисляющие результат деления нацело первого аргумента на второй и остаток от деления соответственно

a:= 3 + 8*4; b:= (a div 10) + 14; a:= (b mod 10) + 2; {div и mod - операции, вычисляющие результат деления нацело первого аргумента на второй и остаток от деления соответственно}

a:= 3 + 8*4 b:= div(a,10) + 14 a:= mod(b, 10) + 2 |div и mod - функции, вычисляющие результат деления нацело первого аргумента на второй и остаток от деления соответственно|

1)

a = 0, b = 18

2)

a = 11, b = 19

3)

a = 10, b = 18

4)

a = 9, b = 17

Решение:

а:=3+84=35

b := 35 div 10 + 14= 3+14 =17

a:=17 mod 10 + 2 = 7 + 2=9.

Верный ответ: 4).

2009 год

Определите значение переменной c после выполнения следующего фрагмента программы.

Бейсик

Паскаль

Алгоритмический

a = 5

a = a + 6

b = - a

c = a - 2 * b

a:=5; a:=a+6; b:= -a;

c:=a-2*b;

a:=5 a:=a+6 b:= -a

c:=a-2*b

1) c = -11 2) c = 15 3) c = 27 4) c = 33

Решение:

1) для решения нужно использовать «ручную прокрутку» программы, то есть, выполнить вручную все действия

2) наиболее удобно и наглядно это получается при использовании таблицы, где в первом столбце записаны операторы программы, а в остальных показаны изменения переменных при выполнении этих операторов

3) здесь используются три переменные: a, b, c; до выполнения программы их значения нам неизвестны, поэтому ставим в таблице знаки вопроса:

a

b

c

?

?

?

4) после выполнения оператора a := 5; изменяется значение переменной a:

a

b

c

?

?

?

a := 5;

5

5) оператор a := a + 6; означает «вычислить значение выражения a + 6 используя текущее значение a (равное 5), и записать результат обратно в переменную a»; таким образом, новое значение равно 5 + 6 = 11:

a

b

c

?

?

?

a := 5;

5

a := a + 6;

11

6) следующий оператор, a := a + 6, изменяет значение переменной b, записывая в нее -a; учитывая, что в a записано число 11, находим, что b будет равно -11:

a

b

c

?

?

?

a := 5;

5

a := a + 6;

11

b := -a;

-11

7) последняя команда, c := a - 2*b, изменяет значение переменной c; при текущих значениях a = 11 и b = -11 результат выражения равен 11 - 2*(-11) = 33, это число и будет записано в переменную c:

a

b

c

?

?

?

a := 5;

5

a := a + 6;

11

b := -a;

-11

c := a - 2*b;

33

8) таким образом, правильный ответ - 4.

Тема «Работа с массивами и матрицами в языке программирования»

2006 год

Значения двумерного массива размера 77 задаются с помощью вложенного оператора цикла в представленном фрагменте программы

Бейсик

Паскаль

Алгоритмический

FOR n=1 TO 7

FOR k=1 TO 7

B(n, k)=k-n

NEXT k

NEXT n

for n:=1 to 7 do

for k:=1 to 7 do

B[n, k]:=k-n;

нц для n от 1 до 7

нц для k от 1 до 7

B[n, k]=k-n

кц

кц

Сколько элементов массива будут иметь положительные значения?

1)

49

2)

28

3)

21

4)

7

Решение:

Способ решения основывается на анализе выполнения вложенного цикла. При pавномерном выполнении внутреннего цикла выражение k - n будет положительным при k > n. Так как k и n изменяются от 1 до 7, искомое значение будет равно 6 + 5 + 4 + 3 + 2 + 1 = 21.

Ответ: 21.

2007 год

Значения двух массивов A[1..100] и B[1..100] задаются с помощью следующего фрагмента программы:

Бейсик

Паскаль

Алгоритмический

FOR n=1 TO 100 A(n)=n-10 NEXT n FOR n=1 TO 100 B(n)=A(n)*n NEXT n

for n:=1 to 100 do A[n]:=n-10; for n:=1 to 100 do B[n]:=A[n]*n

нц для n от 1 до 100 A[n]=n-10 кц нц для n от 1 до 100 B[n]=A[n]*n кц

Сколько элементов массива B будут иметь положительные значения?

1)

10

2)

50

3)

90

4)

100

Решение:

A[1]=-9; A[2]=-8;…A[10]=0; A[11]=1; … A[100]=90.

B[1]=-9; B[2]=-16; … B[10]=0; B[11]=11; … B[100]=9000.

N=90

Ответ: 3

2008 год

Значения двух массивов A[1..100] и B[1..100] задаются с помощью следующего фрагмента программы:

Бейсик

Паскаль

Алгоритмический

FOR n=1 TO 100 A(n)=(n-80)*(n-80) NEXT n FOR n=1 TO 100 B(101-n)=A(n) NEXT n

for n:=1 to 100 do A[n]:= (n-80)*(n-80); for n:=1 to 100 do B[101-n]:=A[n];

нц для n от 1 до 100 A[n]=(n-80)*(n-80) кц нц для n от 1 до 100 B[101-n]=A[n] кц

Какой элемент массива B будет наибольшим?

1)

B[1]

2)

B[21]

3)

B[80]

4)

B[100]

Решение:

1) здесь два цикла, в первом из них заполняется массив А, во втором - массив В

2) в элемент массива A[n] записывается квадрат числа n-80; все элементы массива А неотрицательны (как квадраты чисел)

3) посмотрим чему равны некоторые элементы массива А:

A[1] = (1-80)2 = (-79)2 = 792 A[2] = (2-80)2 = (-78)2 = 782

...

A[80] = (80-80)2 = (0)2 = 0 A[81] = (81-80)2 = (1)2 = 1

A[99] = (99-80)2 = 192 A[100] = (100-80)2 = 202

4) таким образом, при увеличении n от 1 до 80 значение A[n] уменьшается от 792 до нуля, а потом (для n > 80) возрастает до 202

5) отсюда следует, что максимальное значение в массиве A - это A[1] = 792

6) во втором цикле для всех номеров n от 1 до 100 выполняется оператор B[101-n] := A[n]; который просто переписывает элементы массива A в массив В, «развертывая» массив в обратном порядке (элемент A[1] будет записан в B[100], а A[100] - в B[1])

7) A[1], наибольший элемент массива А, будет записан в B[100], поэтому B[100] - наибольший элемент в массиве В

Ответ : 4.

2009 год

Дан фрагмент программы, обрабатывающей двухмерный массив A размера n.n.

Бейсик

Паскаль

Алгоритмическ

k = 1

FOR i = 1 TO n

c = A(i,i)

A(i,i) = A(k,i)

A(k,i) = c

NEXT i

k:=1; for i:=1 to n do

begin c:=A[i,i]; A[i,i]:=A[k,i]; A[k,i]:=c end

k:=1 нц для i от 1 до n

c:=A[i,i] A[i,i]:=A[k,i] A[k,i]:=c кц

Представим массив в виде квадратной таблицы, в которой для элемента массива A[i,j] величина i является номером строки, а величина j - номером столбца, в котором расположен элемент. Тогда данный алгоритм меняет местами 1) два столбца в таблице

2) две строки в таблице

3) элементы диагонали и k-ой строки таблицы

4) элементы диагонали и k-го столбца таблицы

Решение:

1)сначала разберемся, что происходит внутри цикла; легко проверить (хотя бы ручной прокруткой, если вы сразу не узнали стандартный алгоритм), что операторы

с:=А[I,i];

A[I,i]:=A[k,i];

A[k,i]:=c;

меняют местами значения A[i,i] и A[k,i], используя переменную c в качестве вспомогательной ячейки;

2)элемент матрицы A[i,i], у которого номера строки и столбца одинаковые, стоит на главной диагонали; элемент A[k,i] стоит в том же столбце i, но в строке с номером k; это значит, что в столбце i меняются местами элемент на главной диагонали и элемент в строке k

i

k

A[k,i]

i

A[i,i]

3)так как эти операторы находятся в цикле, где переменная i принимает последовательно все значения от 1 до n, обмен выполняется для всех столбцов матрицы; то есть, все элементы главной диагонали меняются с соответствующими элементами строки k перед циклом стоит оператор присваивания k := 1;, а после него переменная k не меняется; поэтому в программе элементы главной диагонали обмениваются с первой строкой.

Ответ :3.

Тема «Условные операторы»

2006 год

Требовалось написать программу, в которой нужно было проверить, лежит ли число x на числовой оси между числами a и b ("между" понимается в строгом смысле, т.е. случай x=a или x=b недопустим). Числа x, a, b являются натуральными, и известно, что a отлично от b (но неизвестно: a>b или b>a). Входная информация вводится с клавиатуры, а на выходе должно быть сообщение вида "x между a и b" (если это действительно так), в противном случае никакой выходной информации не выдается.

Программист торопился и написал программу некорректно.

ПРОГРАММА НА ПАСКАЛЕ

ПРОГРАММА НА БЕЙСИКЕ

VAR a,b,x: integer;

p: integer;

BEGIN

readln(a,b,x);

if (a>x) AND (x>b) then

writeln('x между a,b');

END.

CLS

INPUT a, b, x

IF (a>x) AND (x>b) THEN

PRINT “x между a, b”

END

Последовательно выполните три задания:

1) Приведите пример таких чисел a, b, x, при которых программа работает неправильно.

2) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы. (Это можно сделать несколькими способами, поэтому можно указать любой способ доработки исходной программы).

3) Укажите, как можно доработать программу, соблюдая дополнительное условие: доработанная программа не должна использовать логических операций AND или OR.

Решение:

1) Пример: a=1 x=2 b=3

2) Возможная доработка:

if a<b then begin p:=a; a:=b; b:=p end;

if (a>x) AND (x>b) then

writeln(' x между a,b');

(могут быть и другие правильные способы доработки).

3) Возможная доработка без использования логических операций AND, OR:

p:=(x-a)*(x-b); if p<0 then

writeln(' x между a,b');

(могут быть и другие способы доработки с соблюдением дополнительного условия).

2007 год

Требовалось написать программу, которая решает уравнение «ax+b=0» относительно x для любых чисел a и b, введенных с клавиатуры. Все числа считаются действительными. Программист торопился и написал программу неправильно.

ПРОГРАММА НА ПАСКАЛЕ

ПРОГРАММА НА БЕЙСИКЕ

ПРОГРАММА НА СИ

  • var a, b, x: real;
  • begin
  • readln(a,b,x);
  • if b = 0 then
  • write('x = 0')
  • else
  • if a = 0 then
  • write('нет решений')
  • else
  • write('x =',-b/a);

end.

  • INPUT a, b, x
  • IF b = 0 THEN
  • PRINT "x = 0"
  • ELSE
  • IF a = 0 THEN
  • PRINT "нет решений"
  • ELSE
  • PRINT "x=",-b/a
  • ENDIF
  • ENDIF

END

  • void main(void)
  • { float a,b,x;
  • scanf("%f%f%f", &a,&b,&x);
  • if (b==0)
  • printf("x=0");
  • else
  • if (a==0)
  • printf("нет решений");
  • else
  • printf("x=%f",-b/a);

}

  • Последовательно выполните три задания:
  • 1) Приведите пример таких чисел a, b, x, при которых программа неверно решает поставленную задачу.
  • 2) Укажите, какая часть программы является лишней.
  • 3) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы. (Это можно сделать несколькими способами, поэтому можно указать любой способ доработки исходной программы).
  • Решение:
  • 1) Программа работает неправильно, если a и b равны нулю: в этом случае решением уравнения является любое число x, а программа выдаст только решение . Хотя в задании сказано «Приведите пример таких чисел a, b, x,…», значение x ни на что не влияет , в ответе можно указать любое число x. Например, а=0, b=0, x=0.
  • 2) Лишняя часть программы - ввод x, поскольку это не исходные данные, а результат. Поэтому вместо оператора

readln(a,b,x);

правильнее написать

readln(a,b);

3) Возможная доработка программы - добавить еще один условный оператор, обрабатывающий неучтенный случай (a и b равны нулю), при котором решением является любое число:

var a,b,x: real;

begin

readln(a,b);

if b = 0 then

if a = 0 then

write('любое число')

else write('x = 0')

else

if a = 0 then

write('нет решений')

else write('x =',-b/a);

end.

Можно еще немного оптимизировать программу: заметим, что в обеих частях первого условного оператора встречается оператор if a = 0 then; его можно «вынести» наверх, сделать внешним, а не вложенным:

if а = 0 then

if b = 0 then

write('любое число')

else write('нет решений')

else

write('x=',-b/a);

2008 год

Требовалось написать программу, которая решает уравнение «a|x|=b» относительно x для любых чисел a и b, введенных с клавиатуры. Все числа считаются действительными. Программист торопился и написал программу неправильно.

ПРОГРАММА НА ПАСКАЛЕ

ПРОГРАММА НА БЕЙСИКЕ

ПРОГРАММА НА СИ

var a,b,x: real;

begin

readln(a,b,x);

if a = 0 then

if b = 0 then

write ('любое число')

else

write ('нет решений')

else

if b = 0 then

write('x = 0')

else

write('x =',b/a,' или x =',-b/a);

end.

INPUT a, b, x

IF a = 0 THEN

IF b = 0 THEN

PRINT "любое число"

ELSE

PRINT "нет решений"

ENDIF

ELSE

IF b = 0 THEN

PRINT "x = 0"

ELSE

PRINT "x =",b/a, " или x =",-b/a

END IF

END IF

END

void main(void)

{float a,b,x;

scanf("%f%f%f", &a,&b,&x);

if (a==0)

if (b==0)

printf("любое число");

else

printf ("нет решений");

else

if (b==0)

printf("x = 0");

else

printf("x=%f или x=%f", b/a,-b/a);

}

Последовательно выполните три задания:

1) Приведите пример таких чисел a, b, x, при которых программа неверно решает поставленную задачу.

2) Укажите, какая часть программы является лишней.

3) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы. (Это можно сделать несколькими способами, поэтому можно указать любой способ доработки исходной программы).

Решение:

1) Программа работает неправильно, если a и b не равны нулю и имеют разные знаки: в этом случае уравнение не имеет решений (поскольку модуль - неотрицательная величина), а программа выдаст два решения. Хотя в задании сказано «Приведите пример таких чисел a, b, x,…», значение x ни на что не влияет , в ответе можно указать любое число x. Например, а=1, b=-1, x=0.2) Лишняя часть программы - ввод x, поскольку это не исходные данные, а результат. Поэтому вместо оператора

readln(a,b,x);

правильнее написать

readln(a,b);

3)Возможная доработка программы - добавить еще один условный оператор, обрабатывающий неучтенный случай (a и b не равны нулю и имеют разные знаки), при котором нет решений:

var a,b,x: real;

begin

readln(a,b);

if a = 0 then

if b = 0 then

write ('любое число')

else write ('нет решений')

else

if b = 0 then

write('x = 0')

else

if a*b<0 then

write(`нет решений')

else write('x =',b/a,' или x =',-b/a);

end.

Для проверки условия «a и b имеют разные знаки» использовано произведение a*b, которое больше нуля, когда два значения имеют одинаковые знаки, и меньше нуля - когда разные.

2009 год

Требовалось написать программу, которая вводит с клавиатуры координаты точки на плоскости (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.

INPUT x, y

IF y<=1 THEN

IF x>=0 THEN

IF y>=SIN(x) THEN

PRINT "принадлежит"

ELSE

PRINT "не принадлежит"

ENDIF

ENDIF

ENDIF

END

void main(void)

{ float x,y;

scanf("%f%f",&x,&y);

if (y<=1)

if (x>=0)

if (y>=sin(x))

printf("принадлежит");

else

printf("не принадлежит");

}

Последовательно выполните следующее:

1) Приведите пример таких чисел x, y, при которых программа неверно решает поставленную задачу.

2) Укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы. (Это можно сделать несколькими способами, поэтому можно указать любой способ доработки исходной программы.)

Решение:

1) сначала лучше отложить в сторону программу и попытаться написать условие, которым должны отвечать точки, попавшие в выделенную область

2) заштрихованная область ограничена по координате , она находится

· справа от оси , что равносильно условию (с учетом границы здесь и далее получаем нестрогие неравенства)

· слева от первого максимума функции ; из математики мы знаем, что эта функция достигает максимума при , поэтому получаем второе условие

3) заштрихованная область ограничена с двух сторон по координате : она находится

· ниже линии , откуда следует третье условие

· выше линии , что дает четвертое условие

4) итак, точка находится в заданной области, если все эти четыре условия выполняются одновременно; можно предположить, что в программе нужно использовать четыре вложенных условных оператора или один условный оператор, в котором четыре простых условия (отношения , , и ) связаны с помощью логической операции and («И», одновременное выполнение всех условий)

5) теперь смотрим на программу: здесь три вложенных условных оператора с простыми отношениями, поэтому явно какое-то условие не учтено; легко найти, что «забыли» условие

6) оператор write('принадлежит') помещен внутрь всех трех условных операторов, то есть, он выполнится тогда, когда три (а не четыре!) условия истинны;

7) отметим на рисунке область, где выполняются все нужные условия, кроме (красная зона);

8) для всех точек, которые находятся в «красной» зоне программа выдаст сообщение «принадлежит», хотя в самом деле эти точки не принадлежит заданной области; одна из таких точек имеет координаты x=р, y=0,5

9) теперь выясним, когда программа выдает сообщение «не принадлежит»

if x>=0 then

if y>-=sin (x) then

write(`принадлежит')

else write(`не принадлежит')

10) судя по записи «лесенкой», else относится к самому первому оператору if, однако в самом деле это не так; перед словом else нет end, поэтому ищем ближайший if: это самый внутренний оператор, правильная запись «лесенкой» выглядит так:

if y<=1 then

if x>=0 then

if y>=sin (x) then

write(`принадлежит')

else write(`не принадлежит')

Этот фрагмент программы соответствует блок-схеме, которая показана на рисунке справа:

11) по схеме видим, что при (первое условие ложно), а также при (второе условие ложно) программа вообще не выдает никакого сообщения, то есть, работает неправильно; таким образом, координаты любой точки, для которой или , могут быть указаны в ответе как пример набора входных данных, при которых программа работает неправильно

12) итак, первая часть ответа такова: примеры входных данных, на которых программа работает неверно: (x=3.14, y=0.5) (неправильно определяет принадлежность точки области) (x=0, y=1) или (x=-1, y=0) (не выдает вообще никакого сообщения)

13) остается исправить эту программу; начнем с самого «лобового способа»: добавим в программу четвертый (вложенный) условный оператор, проверяющий условие , и еще три блока else, чтобы выводить строку «не принадлежит» в том случае, когда хотя бы один из них не сработал:

if x<=pi/2 then

if y<=1 then

if x>=0 then

if y>=sin (x) then

write(`принадлежит')

else write(`не принадлежит')

else write(`не принадлежит')

else write(`не принадлежит')

else write(`не принадлежит')

else write(`не принадлежит')

14) хотя приведенный выше метод дает работоспособную программу, она получается слишком длинная и некрасивая для такой простой задачи; достаточно сказать, что оператор write('не принадлежит') повторяется в тексте 4 раза

15) более элегантное решение формулируется на словах так: «точка принадлежит области, если выполняются одновременно 4 приведенных выше условия, а иначе - не принадлежит»; а вот реализация на Паскале (приведем программу-ответ целиком):

var x,y: real;

begin

readln(x, y);

if (x>=0) and (x<=pi/2) and

(y<=1) and (y>= sin (x)) then

write(`принадлежит')

else write (`не принадлежит');

end.

здесь использовано сложное условие, в котором 4 отношения связаны операциями and («И», требуется одновременное выполнение всех условий).

Тема «Обработка массива»

2006 год

Опишите на русском языке или на одном из языков программирования алгоритм поиска второго по величине (т.е. следующего по величине за максимальным) элемента в числовом массиве из 30 различных элементов.

Решение:

const N=30;

var a:array[1..N] of real;

Max1, Max2, i: real;

begin

Max1:=a[1];

Max2:=a[1];

if a[2]>Max1 then Max1:=a[2]

else Max2:=a[2];

for i:=3 to N do

begin

if a[i]>Max1 then

begin Max2:=Max1;

Max1:=a[i];

end

else if a[i]>Max2 then

Max2:=a[i];

end;

writeln(Max2);

end.

2007 год

Опишите на русском языке или одном из языков программирования алгоритм поиска номера первого из двух последовательных элементов в целочисленном массиве из 30 элементов, сумма которых максимальна (если таких пар несколько, то можно выбрать любую из них).

Решение:

1) Выделяем целочисленные переменные i1 и Sum; в i1 будем хранить номер первого в паре выбранных соседних элементов, а в Sum - их сумму. В i1 записываем начальное значение 1, а в Sum - сумму первых двух элементов. В цикле рассматриваем все элементы массива со второго до N-1, если сумма текущего элемента и следующего за ним больше Sum, то запоминаем эту сумму в переменной Sum, а номер текущего элемента - в i1.

Const N=30;

var A: array[1..N] of integer;

i,i1,Sum: integer;

begin

for i:=1 to N do readln(A[i]);

i1:=1;

Sum:=A[1]+A[2];

for i:=2 to N-1 do

if A[i]+A[i+1]> Sum then begin

i1:=I;

Sum:= A[i]+ A[i+1];

end

writeln(i1);

end.

2008 год

Опишите на русском языке или одном из языков программирования алгоритм подсчета максимального количества подряд идущих совпадающих элементов в целочисленном массиве длины 30.

Решение:

1) сначала нужно понять задачу; предположим, что в массиве есть одинаковые элементы, стоящие рядом:

1

1

2

2

1

1

1

1

3

3

2

2

2) самая длинная цепочка стоящих рядом элементов в данном случае состоит из 4-х единиц (она выделена желтым фоном)

3) нам нужно по крайней мере две переменных: для хранения номера текущего элемента (при обработке массива в цикле) и для хранения максимального количества идущих подряд элементов (обозначим ее kMax)

4) в целом (пока неточный) алгоритм может выглядеть так: «пройти весь массив, подсчитывая для каждого элемента длину цепочки подряд идущих одинаковых чисел, если эта длина больше kMax, то записать ее в kMax»

5) отсюда сразу следует, что необходима еще одна переменная (обозначим ее через k), показывающая для каждого элемента массива длину цепочки одинаковых чисел, которая заканчивается на этом элементе:

1

1

2

2

1

1

1

1

3

3

2

2

k

1

2

1

2

1

2

3

4

1

2

1

2

kMax

1

2

2

2

2

2

3

4

4

4

4

4

6) следующий шаг к решению: нужно понять, как изменять переменную k при проходе по массиву; можно сделать так: если очередной элемент равен предыдущему, счетчик k увеличиваем на единицу, а если не равен - записываем в него 1 (цепочка одинаковых чисел кончилась, началась новая, в ней пока один элемент)

7) при таком подходе проблема может возникнуть при просмотре первого элемента, потому что для него нет предыдущего; поэтому описанную выше процедуру будем в цикле применять ко всем элементам массива, начиная со второго (а не с первого); в самом начале программы запишем в k и kMax по единице - таким образом, мы «вручную» (без цикла) рассмотрели первый элемент массива

8) теперь можно написать алгоритм на русском языке: «Выделим две вспомогательные переменные, k и kMax, и запишем в каждую из них по единице. В цикле рассматриваем все элементы массива со второго до последнего, если очередной элемент равен предыдущему, увеличиваем k; если k > kMax, записываем в kMax значение k. В конце цикла в kMax окажется требуемое значение».

9) этот алгоритм реализуется в такой программе:

i,k,kMax: integer;

begin

for i:=1 to N do readln(A[i];

k:=1;

kMax:=1;

for i:=2 to N do begin

if A[i] = A[i-1] then

k:=k+1

else k:=1;

if k>kMax then kMax:=k;

end;

writeln(kMax);

end.

2009 год

Опишите на русском языке или одном из языков программирования алгоритм получения из заданного целочисленного массива размером 30 элементов другого массива, который будет содержать модули значений элементов первого массива (не используя специальной функции, вычисляющей модуль числа).

1) сначала лучше (прежде всего, для себя) написать алгоритм на русском языке (или на псевдокоде - это нечто среднее между словесным алгоритмом и готовой программой)

2)по условию нужно выделить в памяти два массива одинакового размера, назовем их A и B; обозначим размер массивов через N, индексы элементов изменяются от 1 до N;

3)в цикле в каждый элемент B[i] массива B нужно записать модуль соответствующего элемента A[i] массива A, это нужно сделать для всех i от 1 до N

4)есть небольшая сложность: запрещено использовать стандартную функцию вычисления модуля; согласно определению модуля решение может быть такое: если элемент A[i] больше нуля, записываем в B[i] его значение без изменений, а если меньше нуля - меняем знак, то есть, в B[i] записываем (-A[i])

5)решение в виде алгоритма на русском языке может выглядеть так: «Выделяем в памяти второй массив того же размера. В цикле рассматриваем все элементы первого массива с первого до последнего. Если текущий элемент больше нуля или равен нулю, в соответствующий элемент второго массива записываем его значение без изменений; если текущий элемент меньше нуля, во второй массив записываем значение элемента с обратным знаком».

6)осталось написать программу, практически дословно реализующую это решение:

const N=30;

var a, b:array[1..N] of integer;

i: integer;

begin

for i:=1 to N do read(a[i]);

for i:=1 to N do

if a [i] < 0

then b[i]:= - a[i]

else b[i]:= a[i];

end

7) размер массива грамотно задавать через константу (const N = 30;), а не вписывать число в каждый цикл; тогда, если нужно будет переделать программу для массива другого размера, достаточно будет изменить всего одно число в начале программы.

Тема «Обработка символьных строк»

2006 год

Вступительные испытания в некоторый вуз состоят из трех экзаменов: математика (максимальный балл - 9), информатика (максимальный балл - 9), литература (максимальный балл - 5). На вход программе подаются сведения о сдаче этих экзаменов абитуриентами. В первой строке вводится количество абитуриентов N, во второй - количество мест K (K < N) на которые эти абитуриенты претендуют. Каждая из следующих N строк имеет следующий формат: <Фамилия> <оценка1> <оценка2> <оценка3>, где <Фамилия> - строка, состоящая не более, чем из 20 символов, оценки - числа от 0 до максимальной оценки по предмету соответственно. (Ноль ставится в случае, если экзамен не сдавался, например, после полученной на предыдущем экзамене двойки. Все баллы, большие 2, считаются удовлетворительными). Пример входных строк:

Иванов 8 9 3

Петров 2 0 0

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

Решение: Алгоритм решения этой задачи основан на использовании метода подсчета. Введем массив m:array[0..23] of integer, в p-м элементе которого будем подсчитывать количество абитуриентов, набравших p баллов. Если абитуриент получил хотя бы одну двойку, то удобно считать, что его общий балл равен 0. Заполнять массив m будем в процессе считывания данных, сами данные хранить не будем. Заметим, что сумма всех элементов массива m равна n -- числу абитуриентов. Взять на первый курс могут только k человек. Здесь возможна ситуация, что есть группа абитуриентов, набравших одинаковое количество баллов p, но если их всех зачислить на первый курс вместе с абитуриентами, набравшими больше чем p баллов, то мест не хватит (это и есть полупроходной балл). Для определения полупроходного балла будем подсчитывать сумму элементов этого массива (т.е. число абитуриентов), начиная с 23-го, до тех пор, пока она не превосходит K (алгоритм подсчета суммы элементов массива также относится к базовым). Индекс первого элемента массива, который не войдет в эту сумму и будет искомым полупроходным баллом. Если проходной балл набрали ровно K абитуриентов, то программа сообщает, что полупроходной балл отсутствует.

Программа:

var m:array[0..23] of integer;

c:char;

i, K, N, S, m1, m2, m3:integer;

begin

readln(N); readln(K);

for i:=0 to 23 do m[i]:=0;

for i:=1 to N do

begin

repeat

read(c)

until c=' '; {считана фамилия абитуриента}

readln(m1, m2, m3);

if (m1<3)or(m2<3)or(m3<3) then s:=0

else s:=m1+m2+m3;

m[s]:=m[s]+1 {учитываем абитуриента в элементе массива, соответствующем его баллам}

end;

s:=m[23]; i:=23;

while s+m[i-1]<=K and

(i>9) {9 - минимально возможный балл} do

begin

i:=i-1;

s:=s+m[i]

end;

if (s<K)and(i>9) then

writeln('полупроходной балл набрали', m[i-1],

' человек')

else writeln('полупроходной балл отсутствует');

readln

end.

2007 год

На вход программе подаются сведения о сдаче экзаменов учениками 9-х классов некоторой средней школы. В первой строке сообщается количество учеников N, которое не меньше 10, но не превосходит 100, каждая из следующих N строк имеет следующий формат: <Фамилия> <Имя> <оценки>, где <Фамилия> - строка, состоящая не более чем из 20 символов, <Имя> - строка, состоящая не более чем из 15 символов, <оценки> - через пробел три целых числа, соответствующие оценкам по пятибалльной системе. <Фамилия> и <Имя>, а также <Имя> и <оценки> разделены одним пробелом. Пример входной строки:

Иванов Петр 4 5 4

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

Решение:

1) сначала составим программу в самом общем виде на псевдокоде, чтобы определить ее основные блоки, а потом будем их постепенно «расшифровывать» через операторы языка программирования:

{читаем все данные и запоминаем их}

{находим три худших результата}

{выводим фамилии и имена тех, чей результат меньше или равен «третьему худшему»}

2) до того, как начать писать «нормальный» код, нужно определить, как хранить данные; в данном случае нужно запомнить несколько данных по каждому ученику, их удобнее объединить в запись с двумя полями (фамилия-имя и сумма баллов); таких записей нужно выделить в памяти не менее 100 (по условию), то есть, массив из 100 элементов:

const LIM=100

var Info: array [1..LIM] of record

name: string;

sum: integer;

end;

Чтение данных:

3) после того, как мы прочитали фактическое число учеников N, в цикле считываем и расшифровываем информацию о них, сохраняя все данные в структурах

for i:=1 to N do begin

{ считываем строку данных }

Info[i].name := { фамилия и имя };

Info[i].sum := { сумма баллов };

end;

4) здесь, в принципе, можно использовать тот же подход, что и в первой задаче - читаем строку целиком, затем «разбираем» ее на части с помощью стандартных функций - однако, для разнообразия, мы используем другой подход - будем читать информацию посимвольно, то есть, считывая по одному символу в переменную c типа char;

5) сначала в поле name очередной структуры записываем пустую строку ''(в которой нет ни одного символа, длина равна нулю)

Info[i].name := ''; { пустая строка }

6) затем считываем символы фамилии и сразу приписываем их в конец поля name:

repeat

read ( c );

Info[i].name := Info[i].name + c;

until c = ' '; { пока не прочитали пробел }

7) затем также читаем из входного потока имя, до пробела, и записываем его в конец того же поля name:

repeat

read ( c );

Info[i].name := Info[i].name + c;

until c = ' '; { пока не прочитали пробел }

заметьте, что эти два цикла одинаковы, поэтому ввод имени и фамилии можно записать в виде вложенного цикла так:

Info[i].name := ''; { пустая строка }

for k:=1 to 2 do

repeat

read ( c );

Info[i].name := Info[i].name + c;

until c = ' '; { пока не прочитали пробел }

8) важно! обратите внимание, что для организации внутреннего цикла используется другая переменная, k (а не i, потому что i - переменная главного цикла, она обозначает номер текущего ученика)

9) теперь во входном потоке остались три числа, которые мы можем последовательно считывать в целую переменную mark, а затем - добавлять к полю Info[i].sum:

Info[i].sum := 0;

for k:=1 to 3 do begin

read(mark);

Info[i].sum := Info[i].sum + mark;

end;

readln;

10)последняя команда readln пропускает все оставшиеся символы до новой строки (из этой мы прочитали все, что нужно)

11)вот полный цикл ввода данных, после его окончания все исходные данные будут записаны в первые N записей массива Info:

for i:=1 to N do begin

{ ввод имени и фамилии }

Info[i].name := '';

for k:=1 to 2 do

repeat

read(c);

Info[i].name := Info[i].name + c;

until c = ' ';

{ ввод и суммирование оценок }

Info[i].sum := 0;

for k:=1 to 3 do begin

read(mark);

writeln(mark);

Info[i].sum := Info[i].sum + mark;

end;

readln;

end;

12)выделим в памяти три целых переменных: min1 (минимальный), min2 («второй минимальный»), min3 («третий минимальный»), в виде начальных значений запишем в каждую из них число, заведомо превышающее максимальную возможную сумму трех оценок, например, 20 (>5+5+5)

13)полный цикл поиска выглядит так:

min1 := 20; min2 := 20; min3 := 20;

for i:=1 to N do begin

if Info[i].sum < min1 then begin { новый min1 }

min3 := min2; min2 := min1;

min1 := Info[i].sum;

end

else if Info[i].sum < min2 then begin { новый min2 }

min3 := min2;

min2 := Info[i].sum;

end

else if Info[i].sum < min3 then { новый min3 }

min3 := Info[i].sum;

end;

14)обратим внимание на два момента: во-первых, когда переезжают два элемента, сначала нужно перемещать второй на место третьего, а потом - первый на место второго:

min3 := min2;

min2 := min1;

эти операторы нельзя менять местами, иначе «старое» значение min2 будет потеряно;

во-вторых, если проверять условие Info[i].sum < min2 нужно только тогда, когда очередная сумма не меньше, чем min1, поэтому каждый следующий условный оператор стоит в else-блоке предыдущего, то есть, выполняется только тогда, когда предыдущий не сработал

15)итак, мы нашли три минимальных результата, и остается вывести на экран фамилии и имена тех, у кого сумма баллов меньше или равна min3:

for i:=1 to N do

if Info[i].sum <= min3 then

writeln(Info[i].name);

16)на всякий случай приведем полную программу, она получилась довольно длинная

const LIM = 100;

var Info: array[1..LIM] of record

name: string;

sum: integer;

end;

i, k, N, mark, min1, min2, min3: integer;

c: char;

begin

readln(N);

{ ввод исходных данных }

for i:=1 to N do begin

Info[i].name := '';

for k:=1 to 2 do

repeat

read(c);

Info[i].name := Info[i].name + c;

until c = ' ';

Info[i].sum := 0;

for k:=1 to 3 do begin

read(mark);

writeln(mark);

Info[i].sum := Info[i].sum + mark;

end;

readln;

end;

{ поиск трех минимальных }

min1 := 20; min2 := 20; min3 := 20;

for i:=1 to N do begin

if Info[i].sum <min1 then begin

min3 := min2; min2 := min1;

min1 := Info[i].sum;

end

else if Info[i].sum <min2 then begin

min3 := min2;

min2 := Info[i].sum;

end

else if Info[i].sum <min3 then

min3 := Info[i].sum;

end;

{ вывод результата }

for i:=1 to N do

if Info[i].sum <= min3 then

writeln(Info[i].name);

end.

17)эту задачу можно решить и без записей, используя два массива: массив символьных строк name и массив целых чисел sum, они объявляются так:

var name: array[1..MAX] of string;

sum: array[1..MAX] of integer;

после этого в приведенной программе нужно заменить везде Info[i].name на name и Info[i].sum на sum.

2008 год

На вход программе подаются сведения о номерах школ учащихся, участвовавших в олимпиаде. В первой строке сообщается количество учащихся N, каждая из следующих N строк имеет формат: <Фамилия> <Инициалы> <номер школы>, где <Фамилия> - строка, состоящая не более чем из 20 символов, <Инициалы> - строка, состоящая из 4-х символов (буква, точка, буква, точка), <номер школы> - не более чем двузначный номер. <Фамилия> и <Инициалы>, а также <Инициалы> и <номер школы> разделены одним пробелом. Пример входной строки:

Иванов П.С. 57

Требуется написать как можно более эффективную программу (укажите используемую версию языка программирования, например, Borland Pascal 7.0), которая будет выводить на экран информацию, из каких школ было меньше всего участников олимпиады (но из этих школ был хотя бы один участник).

Решение:

1) по условию, единственная информация, которая нам нужна в итоге для вывода результата - это количество участников по каждой школе

2) так как номер школы состоит (по условию!) не более, чем из двух цифр, всего может быть не более 99 школ (с номерами от 1 до 99)

3) поэтому можно ввести массив C из 99 элементов; для всех k от 1 до 99 элемент C[k] будет ячейкой-счетчиком, в которой накапливается число участников от школы с номером k; сначала во все элементы этого массива записываются нуль (обнуление счетчиков):

for k:=1 to 99 do C[k]:=0;

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

4) основной цикл обработки вводимых строк можно записать на псевдокоде так:

for i:=1 to N do begin

{ читаем очередную строку }

{ определяем номер школы k }

C[k] := C[k] + 1; { увеличиваем счетчик k-ой школы }

end;

5) поскольку данные вводятся в виде символьной строки, нужно выделить в памяти переменную s типа string

6) для чтения очередной строки будем использовать оператор readln

7) остается понять, как выделить из строки номер школы; по условию он закодирован в последней части строки, после второго пробела; значит, нужно найти этот второй пробел, вырезать из строки весь «хвост» после этого пробела, и преобразовать его из символьного формата в числовой

8) чтобы найти первый пробел и «отрезать» первую часть строки с этим пробелом, можно использовать команды

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

первая команда определяет номер первого пробела и записывает его в целую переменную p, в вторая - записывает в строку s весь «хвост», стоящий за этим пробелом, начиная с символа с номером p+1; длина хвоста равна Length(s)-p, где Length(s) - длина строки;

9) поскольку нас интересует часть после второго пробела, эти две строчки нужно повторить два раза, в результате в переменной s окажется символьная запись номера школы, для преобразования ее в форму числа можно использовать функцию Val:

Val(s, k, r);

эта процедура (Turbo Pascal, Borland Pascal, PascalABC, среда АЛГО) преобразует символьную строку s в числовое значение k; с помощью переменной r обнаруживается ошибка: если раскодировать число не удалось (в строке не число), в r будет записан нуль (здесь мы не будем обрабатывать эту ошибку, полагая, что все данные правильные);

если вы работаете на ПаскалеABC (никто не может вам запретить написать, что этот так), вместо Val можно использовать более удобную и понятную функцию StrToInt:

k := StrToInt(s);

10) таким образом, основной цикл выглядит так:

for i:=1 to N do begin

readln(s); { читаем очередную строку }

{ выделяем часть после второго пробела }

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

{ определяем номер школы k }

Val(s, k, r);

C[k] := C[k] + 1; { увеличиваем счетчик k-ой школы }

end;

11) заметим, что можно избежать дублирования двух строк в теле цикла, «свернув» их во внутренний цикл, но это вряд ли сильно упростит запись:

for k:=1 to 2 do begin

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

end;

12) дальше стандартным алгоритмом определяем в массиве C минимальный элемент Min, не учитывая нули (школы, из которых не было участников):

Min := N;

for k:=1 to 99 do

if (C[k] <> 0) and (C[k]<Min) then Min := C[k];

здесь интересна первая строчка, Min:=N: по условию всего было N участников, поэтому минимальное значение не может быть больше N; обратите внимание, что привычный вариант (который начинается с Min:=C[1]) работает неверно, если из первой школы не было ни одного участника

13) и выводим на экран номера всех школ (обратите внимание - номера!), для которых C[k]=Min:

for k:=1 to 99 do

if C[k] = Min then writeln(k);

14) остается «собрать» программу, чтобы получилось полное решение; максимальное количество школ мы задали в виде константы LIM:

const LIM = 99;

var C:array[1..LIM] of integer;

i, p, N, k, r, Min: integer;

s:string;

begin

readln(N);

for i:=1 to N do begin

readln(s); { читаем очередную строку }

{ выделяем часть после второго пробела }

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

{ определяем номер школы k }

Val(s, k, r);

C[k] := C[k] + 1; { увеличиваем счетчик k-ой школы }

end;

Min := N;

for k:=1 to LIM do

if (C[k] <> 0) and (C[k]<Min) then Min := C[k];

for k:=1 to LIM do

if C[k] = Min then writeln(k);

end.

2009 год

На вход программе подаются сведения о номерах школ учащихся, участвовавших в олимпиаде. В первой строке сообщается количество учащихся N, каждая из следующих N строк имеет формат: <Фамилия> <Инициалы> <номер школы>, где <Фамилия> - строка, состоящая не более чем из 20 символов, <Инициалы> - строка, состоящая из 4-х символов (буква, точка, буква, точка), <номер школы> - не более чем двузначный номер. <Фамилия> и <Инициалы>, а также <Инициалы> и <номер школы> разделены одним пробелом. Пример входной строки:

Иванов П.С. 57

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

Следует учитывать, что N>=1000.

Решение:

1) по условию, единственная информация, которая нам нужна в итоге для вывода результата - это количество участников по каждой школе

2) так как номер школы состоит (по условию!) не более, чем из двух цифр, всего может быть не более 99 школ (с номерами от 1 до 99)

3) поэтому можно ввести массив C из 99 элементов; для всех k от 1 до 99 элемент C[k] будет ячейкой-счетчиком, в которой накапливается число участников от школы с номером k; сначала во все элементы этого массива записываются нуль (обнуление счетчиков):

for k:=1 to 99 do C[k]:=0;

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

4) основной цикл обработки вводимых строк можно записать на псевдокоде так:

for i:=1 to N do begin

{ читаем очередную строку }

{ определяем номер школы k }

C[k] := C[k] + 1; { увеличиваем счетчик k-ой школы }

end;

5) поскольку данные вводятся в виде символьной строки, нужно выделить в памяти переменную s типа string

6) для чтения очередной строки будем использовать оператор readln

7) остается понять, как выделить из строки номер школы; по условию он закодирован в последней части строки, после второго пробела; значит, нужно найти этот второй пробел, вырезать из строки весь «хвост» после этого пробела, и преобразовать его из символьного формата в числовой

8) чтобы найти первый пробел и «отрезать» первую часть строки с этим пробелом, можно использовать команды

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

первая команда определяет номер первого пробела и записывает его в целую переменную p, в вторая - записывает в строку s весь «хвост», стоящий за этим пробелом, начиная с символа с номером p+1; длина хвоста равна Length(s)-p, где Length(s) - длина строки;

9) поскольку нас интересует часть после второго пробела, эти две строчки нужно повторить два раза, в результате в переменной s окажется символьная запись номера школы, для преобразования ее в форму числа можно использовать функцию Val:

Val(s, k, r);

эта процедура (Turbo Pascal, Borland Pascal, PascalABC, среда АЛГО) преобразует символьную строку s в числовое значение k; с помощью переменной r обнаруживается ошибка: если раскодировать число не удалось (в строке не число), в r будет записан нуль (здесь мы не будем обрабатывать эту ошибку, полагая, что все данные правильные);

если вы работаете на ПаскалеABC (никто не может вам запретить написать, что этот так), вместо Val можно использовать более удобную и понятную функцию StrToInt:

k := StrToInt(s);

10) таким образом, основной цикл выглядит так:

for i:=1 to N do begin

readln(s); { читаем очередную строку }

{ выделяем часть после второго пробела }

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

{ определяем номер школы k }

Val(s, k, r);

C[k] := C[k] + 1; { увеличиваем счетчик k-ой школы }

end;

11) заметим, что можно избежать дублирования двух строк в теле цикла, «свернув» их во внутренний цикл, но это вряд ли сильно упростит запись:

for k:=1 to 2 do begin

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

end;

12) дальше стандартным алгоритмом определяем в массиве C минимальный элемент Min, не учитывая нули (школы, из которых не было участников):

Min := N;

for k:=1 to 99 do

if (C[k] <> 0) and (C[k]<Min) then Min := C[k];

здесь интересна первая строчка, Min:=N: по условию всего было N участников, поэтому минимальное значение не может быть больше N; обратите внимание, что привычный вариант (который начинается с Min:=C[1]) работает неверно, если из первой школы не было ни одного участника

13) и выводим на экран номера всех школ (обратите внимание - номера!), для которых C[k]=Min:

for k:=1 to 99 do

if C[k] = Min then writeln(k);

14) остается «собрать» программу, чтобы получилось полное решение; максимальное количество школ мы задали в виде константы LIM:

const LIM = 99;

var C:array[1..LIM] of integer;

i, p, N, k, r, Min: integer;

s:string;

begin

readln(N);

for i:=1 to N do begin

readln(s); { читаем очередную строку }

{ выделяем часть после второго пробела }

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

p := Pos(' ', s);

s := Copy(s, p+1, Length(s)-p);

{ определяем номер школы k }

Val(s, k, r);

C[k] := C[k] + 1; { увеличиваем счетчик k-ой школы }

end;

Min := N;

for k:=1 to LIM do

if (C[k] <> 0) and (C[k]<Min) then Min := C[k];

for k:=1 to LIM do

if C[k] = Min then writeln(k); end.

Методические рекомендации для учителей по совершенствованию методики преподавания информатики с учетом результатов ЕГЭ

Выскажу некоторые рекомендации по подготовке школьников к сдаче ЕГЭ по информатике, который с 2009 года вышел за рамки эксперимента.

Работу по подготовке к экзамену в формате ЕГЭ можно разбить на две части. Первая состоит в том, что начиная с 8-го класса в планы уроков вносятся изменения, ориентированные на подготовку к ЕГЭ практически на каждом уроке. Вторая часть предполагает разработку программы дополнительных занятий, элективных курсов по подготовке выпускников непосредственно к сдаче экзамена

В плане практически каждого урока должно быть предусмотрено время (от 5 до 15 минут) на тестирование, объем таких мини-тестов -- 5--10 вопросов. Желательно при закреплении материала на уроке давать контрольные вопросы и задания в стандартном формате, соответствующем ЕГЭ. Планы уроков начиная с 8-го класса должны заканчиваться пунктом "Примеры заданий из ЕГЭ". Широкое использование систем тестового контроля не только позволит исподволь подготовить учащихся к формату письменных экзаменов, проводимых в виде тестов, но и явится несомненным подспорьем на уроках информатики. Такие тесты, умело составленные, могут выполнять не только контролирующие, но обучающие и закрепляющие функции, служить для осуществления как текущего или промежуточного, так и тематического или итогового контроля знаний.


Подобные документы

  • Структура программы Pascal и алгоритмы решения задач. Работа с циклическими операторами, массивами, процедурами. Составление блок-схем задач. Операции над матрицами в программе MathCad. Работа формулами, графиками и диаграммами в оболочке MS Excel.

    курсовая работа [459,0 K], добавлен 13.08.2012

  • История и основы структурного программирования в среде Turbo Pascal. Работа с различными типами данных. Операторы языка. Работа с символьными и строковыми переменами, одномерным, двумерным массивами. Классификация компьютерных игр. Игры на языке Паскаль.

    курсовая работа [28,8 K], добавлен 06.05.2014

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

    курсовая работа [75,0 K], добавлен 21.03.2013

  • Основные типы циклов программирования. Методы применения специальных функций break, continue и цикла while. Обработка массивов информации. Условия применения циклических алгоритмов на языке программирования С++. Инициализация одномерного массива.

    курсовая работа [1,7 M], добавлен 06.01.2014

  • Изучение функций и возможностей среды разработки языка программирования Pascal. Рассмотрение работы с одномерными и двумерными массивами, со строками и числами. Математическая формулировка задач. Разработка алгоритмов, описание структуры программ.

    курсовая работа [879,8 K], добавлен 11.02.2016

  • Понятие матриц и операции, выполняемые с ними. Разработка программы для вычислений над матрицами в среде MS Visual Studio Express с применением языка программирования C++. Работа с библиотекой математического типа vector. Реализация перегрузки операций.

    курсовая работа [107,3 K], добавлен 22.12.2010

  • Основные этапы определения радиуса и центра окружности, проходящей через три различные точки заданного множества точек. Особенности построения алгоритма на языке программирования. Составление тестовых примеров для демонстрации возможностей программы.

    контрольная работа [103,9 K], добавлен 21.08.2013

  • Вычисление выражений, использование стандартных функций; работа с графикой. Порядок действий при вычислении, способы ввода данных с клавиатуры. Построение таблиц функций. Организация циклов в программе, итерационные процессы. Работа с массивами чисел.

    контрольная работа [614,7 K], добавлен 16.09.2012

  • Конструкции языка программирования С++, составление простых программ, использyющих оператор if, оператор if else и оператор switch. Работа оператора switch. Создание программы, которая по дате определяет день недели , на который эта дата приходится.

    лабораторная работа [3,1 M], добавлен 03.02.2008

  • Изучение символьных и строковых типов данных, алгоритма задачи на языке программирования Паскаль. Описания получения и установки отдельного символа строки, изменения регистра символов. Анализ создания и просмотра файла, поиска и сортировки информации.

    курсовая работа [440,7 K], добавлен 13.06.2011

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.