понедельник, 9 ноября 2015 г.

Районная олимпиада по программированию - 2015 (8-9 класс)

Самое главное: из 6 участников от нашей школы все 6 заняли призовые места!


Поздравляю победителей!
Марк Приймак - 10 класс - 1 место
Павел Карлин - 10 класс - 2 место
Александр Купченко - 8 класс - 2 место
Максим Васильев - 8 класс - 2 место
Лев Ливинский - 11 класс - 3 место
Константин Устименков - 8 класс - 3 место


А теперь разберем, что было сделано не совсем так, и как надо было сделать правильно.

8-9 класс.

Задача 1.

Найти наибольшее отношение трехзначного числа к сумме его цифр.

Решение.
1. Давайте уточним условие. Вы не просите пользователя вводить числа. Это должен сделать компьютер. Причем компьютер должен перебрать все числа от 100 до 999, для каждого считая результат: ЧИСЛО/(Сумму его цифр)

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

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

Если вам вводят число с клавиатуры, вы должны делить его на разрядные единицы - сотни. десятки, единицы - чтоб потом считать сумму. Я не знаю автора работы, который вплотную приблизился к решению задачи, но все равно сделал не так. как надо. Он упорно считал результат для каждого введенного числа. Но на экран выводил примерно следующее:

Вы ввели число 123
Результат для вашего числа 20,5

НАИБОЛЬШЕЕ ОТНОШЕНИЕ трехзначного числа к сумме его цифр имеет число 100. 
100/1 = 100.

Ребенок вручную посчитал результат и просто сообщал его каждому зашедшему в его программу.

Что НАДО было сделать? Надо было, чтобы компьютер ПЕРЕБРАЛ все варианты от 100 до 999 и выбрал максимальный результат.

Как это нужно было сделать?
Заказываем необходимое количество переменных нужных типов. 
Var
i,j,k,a,b,sum:integer;
max,d:real;

begin
max:=0;  Считаем, для начала, что максимальный результат 0.
a:=0;
b:=0;

А вот тут мы начинаем создавать наши числа, меняя сотни, десятки и                                             единицы. i будет отвечать за количество сотен, поэтому начинается с 1, j будет заведовать десятками, начинается с 0, и k займется единицами, тоже с нуля - таким образом первое из полученных нами чисел будет (i*100+j*10+k), т. е. 100.

For i:=1 to 9 do begin   
  for j:=0 to 9 do begin
    for k:=0 to 9 do begin
     
Сразу считаем сумму цифр. Потом делим наше число на эту сумму. Результат запоминаем в d.
     sum:=i+j+k;
     d:=(i*100+j*10+k)/sum;
Если d оказалось больше максимума, мы запоминаем само число в   a, запоминаем сумму цифр в     b, и меняем максимум на этот улучшенный результат. 
     
 if d>max then 
      begin
        max:=d;
        a:=i*100+j*10+k;
        b:=sum;
        end;
     end;
    end;
   end;

Когда мы отработали все циклы, уже можно поговорить с пользователем - вывести ему сообщение.
   
 Writeln ('Maximum = ',max,' pri delenii ',a,' na ',b);
 end.

Вот и все.


Задача 2.

Дана строка, состоящая из символов, каждый из которых является знаком «+» или цифрой, начинающаяся и заканчивающаяся цифрой. Если в строке встречается сочетание «++», то выдать сообщение об ошибке, в противном случае вычислить получившуюся сумму.

var
  i,res: integer;
begin
  res:=0;
  for i := 1 to length(s) - 1 do
    if (s[i] = '+') and (s[i+1]= '+' ) then
      begin
        write('Error');
        exit;
      end;
  for i := 1 to length(s) do
    if s[i] <> '+' then 
res:= res + StrToInt(s[i]);
  write(res);
end.

Эта задача рассчитана больше на знание языка программирования, чем  на сообразительность. Для решения задачи можно использовать функцию "ORD", которая позволяет получить порядковый номер любого символа согласно таблице ASCII-кодов. Например, номер символа '0' - 48, а номер символа '1' - 49. Как вы понимаете, чтобы получить искомую цифру, необходимо отнять от номера символа 48.

Внимание!
  1. Во входной строке нет пробелов!
  2. Функция ORD будет работать в Turbo Pascal, но не будет работать в Pascal ABC.
  3. Pascal ABS поддерживает синтаксис Delphi, поэтому необходимо заменить строку "res:= res + (ord(s[i])-48);" на "res:= res + StrToInt(s[i]);"

Задача 3.

Между школами поделили N компьютеров Pentium и M компьютеров Celeron. 
Сколько было школ, если известно их не менее K и каждая школа получила 
одинаковое количество компьютеров каждого вида.
Все числа входного файла не превышают 1000000000.
Входные данные
Первая строка содержит натуральные числа N, M, K.
Выходные данные
Единственная строка файла содержит найденное количество школ. Если результатов несколько, то вывести все через пробел в возрастающем
порядке.
Пример входных и выходных данных

input.txt
output.txt
92 138 25
46
Решение
Необходимо найти общие делители чисел M и N, не меньше числа K.
var i,n,m,k,min:integer; f,g:text;
begin assign(f,'input.txt'); reset(f); read(f,n,m,k); close(f);
assign(g,'output.txt'); rewrite(g);
if n>m then min:=m else min:=n;
for i:=k to min do begin if (n mod i=0)and(m mod i=0) then write(g,i,' '); end;
writeln(g); close(g);
end.
В принципе, с задачами 8-9 класса - все. Разобрать. Задать вопросы. Поехали!
Домашняя работа: изучить сайт с олимпиадами за 3 последних года: 

Скачать и разобрать : задачи с решениями

Комментариев нет:

Отправить комментарий