Решите известную задачу из области информатики за кратчайшее время.
В соревновательном программировании задачи не носят исследовательский характер. Эти задачи были решены, как минимум их составителями.
Решить олимпиадную задачу - значит активизировать все свои познания в области информатики для получения кода программы, способного пройти тесты, подготовленные авторами задачи.
Соревновательный компонент олимпиады - необходимость решить предложенные задачи за ограниченное время.
Решение задач - не самоцель.
Основная задача олимпиадного программирования - раскрыть творческий потенциал учащегося, расширить их зону ближайшего развития.
Зачастую олимпиадная задача по программирования состоит из следующих частей:
Художественное описание - история, служащая мотивацией к решению задачи. Сложные задачи сопровождаются коротким описанием, более простые - длинным. Задача учащегося: отфильтровать лишнее, выделить главное.
Описание входных и выходных данных - формат ввода/вывода, ограничения.
Примеры тестовых данных - авторы задач приводят примеры тривиальных тестовых данных. Пограничные случаи должен обнаружить участник.
Используйте архивы прошедших олимпиад для тренировки. Такие задачи могут содержать примеры решений или туториалы - теорию, необходимую для решения задачи.
Используйте архивы задач с автоматической проверкой отправленных решений:
Нужно уделить время развитию навыка классификации задачи по методу её решения.
Кроме последовательного решения однотипных задач, предлагать учащимся ряд разноплановых заданий, подразумевающих разные подходы к решению (использование строк, массивов, итерационных методов, динамического программирования)
Между интерпретируемыми (Python, JavaScript) и компилируемыми языками (C++, C#, Pascal) отдавайте предпочтение компилируемым.
Подробнее остановитесь на доступных типах данных и их ограничениях.
Рассмотрите синтаксические возможности языка, которые позволяют писать более лаконичный код - “синтаксический сахар”.
Уделите внимание изучению встроенных модулей - работа с датой и временем, обработка строк, математические вычисления и так далее.
Важно развивать навык тестирования и отладки кода.
Зачастую, в командных соревнованиях, на одну команду выделяется один компьютер.
Скорость набора кода программы может стать одним из факторов, влияющих на количество заработанных баллов.
Рекомендуйте учащимся использовать клавиатурные тренажёры.
Особое внимание уделить специальным символам: (), [], <>, ;, :, "" и так далее.
Сервисы для измерения скорости набора:
Метод решения задачи основывается непосредственно на формулировке условия. При необходимости варианты решения находятся простым перебором.
На множестве из n точек на плоскости найти две, расположенные друг к другу ближе других.
Для двух точек \(P_i = (x_i, y_i)\) и \(P_j = (x_j, y_j)\): \[ d(P_i,P_j)=\sqrt{(x_i-x_j)^2+(y_i-y_j)^2} \]
static double dist(double x1, double y1, double x2, double y2)
{
return Math.Sqrt(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y1, 2));
}
static void Main(string[] args)
{
const int N = 3; // количество точек
double[] x = new double[N];
double[] y = new double[N];
for (int i = 0; i < N; i++)
{
double xt = Double.Parse(Console.ReadLine());
double yt = Double.Parse(Console.ReadLine());
x[i] = xt;
y[i] = yt;
}
double dMin = 1E300;
int ind1 = -1;
int ind2 = -1;
for (int i = 0; i < N - 1; i++)
{
for (int j = i + 1; j < N; j++)
{
double d = dist(x[i], y[i], x[j], y[j]);
if (d < dMin)
{
dMin = d;
ind1 = i;
ind2 = j;
}
}
}
Console.WriteLine("Первая точка: {0},{1}", x[ind1], y[ind1]);
Console.WriteLine("Вторая точка: {0},{1}", x[ind2], y[ind2]);
}Экземпляр задачи разбивается на несколько меньших экземпляров той же задачи, в идеале - одинакового размера.
Решаются меньшие экземпляры задачи (обычно рекурсивно, хотя иногда для небольших экземпляров применяется какой-нибудь другой алгоритм).
При необходимости решение исходной задачи находится путем комбинации решений меньших экземпляров.
Дан массив из \(n\) чисел. Не используя циклы найдите максимальный элемент массива.
static int PoiskMax(int[] a, int lev, int prav)
{
if (lev == prav)
return a[lev];
else
{
int sred = (lev + prav) / 2;
int levMax = PoiskMax(a, lev, sred);
int pravMax = PoiskMax(a, sred + 1, prav);
return Math.Max(levMax, pravMax);
}
}
static void Main(string[] args)
{
const int N = 10; // количество точек
int[] x = new int[N];
for (int i = 0; i < x.Length; i++)
{
x[i] = int.Parse(Console.ReadLine());
}
int max = PoiskMax(x, 0, N - 1);
Console.WriteLine("Максимальное значение: {0}", max);
}На каждом шаге алгоритм выбирает наилучшую доступную альтернативу в надежде, что последовательность таких выборов приведёт к оптимальному решению задачи.
У вас есть неограниченное количество монет номиналов 1, 5, 10 и 25. Вам нужно составить сумму \(S\) с использованием наименьшего количества монет.
static void Main(string[] args)
{
int[] coins = { 100, 50, 20, 10, 5, 1 };
int S = int.Parse(Console.ReadLine());
int i = 0;
while (S > 0 && i < coins.Length)
{
while(S >= coins[i])
{
S = S - coins[i];
Console.WriteLine(coins[i]);
}
i += 1; // переход к следующему номиналу
}
if (S != 0)
Console.WriteLine("Невозможно разменять сумму {0}", S);
}Динамическое программирование - метод решения задач оптимизации и подсчёта.
Суть метода - сохранение промежуточных вычислений для их повторного использования. Промежуточные решения являются решением подзадач.
Подзадача - задача с меньшим количеством параметров или меньшими значениями параметров.
Решения подзадач сохраняются в одномерных или двухмерных таблицах (массивах или матрицах).
Задача о рюкзаке: Определяет, какие предметы следует взять с собой в рюкзак ограниченной вместимости, чтобы максимизировать общую ценность.
Задача о самой длинной возрастающей подпоследовательности (LIS): Определяет самую длинную подпоследовательность, которая строго возрастает.
Задача о размене монет: Определяет количество способов разменять заданную сумму денег с использованием определенных номиналов монет.
Вычислите \(n\)-ое число Фибоначчи. \[ F(0)=0; F(1)=1; F(n)=F(n-1)+F(n-2) \]
Обычно в условии есть «литературное введение», придающее задаче сюжет. Во введении может, прямо или косвенно, содержаться важная информация, касающаяся условия.
На этом этапе целесообразно построить схему, рисунок, который облегчит понимание условия задачи и поиск ее решения.
Здесь же выделяют известные и неизвестные величины, рассматривая их не только в узко предметном, но и в межпредметном ракурсе.
Построение математической модели исходной задачной ситуации, лежащей в основе ее разрешения.
Построить математическую модель – значит достаточно формально и математически строго понять условие.
Выделяют в явном виде предположения, на которых будет основываться математическая модель; фиксируют соотношения, связывающие результаты с исходными данными.
Разработка алгоритма, которая включает в себя:
выбор метода проектирования алгоритма;
выбор формы записи алгоритма (блок-схемы, псевдокод и др.);
проектирование самого алгоритма.
Собственно написание программы.
Предварительное обсуждение возможных вариантов решения данной задачи на компьютере.
Попытки реализовать решение задачи различными способами, сопоставляя различные альтернативы по эффективности, простоте и универсальности.
Запись и ввод программы на выбранном языке программирования.
Тестирование алгоритма – это проверка правильности или неправильности работы алгоритма на специально заданных тестах или тестовых примерах – задачах с известными входными данными и результатами (иногда достаточны их приближения).
Тестовый набор должен быть минимальным и полным, то есть обеспечивающим проверку каждого отдельного типа наборов входных данных, особенно исключительных случаев.
Грамотный подбор тестов и полное тестирование может дать некоторую картину работоспособности (неработоспособности) программы.
Тестирование алгоритма не может дать полной, 100%-ой гарантии правильности алгоритма для всех возможных наборов входных данных, особенно для достаточно сложных алгоритмов.
это метод пошаговой фиксации динамического состояния алгоритма на некотором тесте.
Часто осуществляется с помощью трассировочных таблиц, в которых каждая строка соответствует определённому состоянию алгоритма, а столбец – определённому состоянию параметров алгоритма (входных, выходных и промежуточных).
Трассировка облегчает отладку и понимание алгоритма.
это процесс поиска и исправления ошибок в алгоритме, явных или неявных.
Тестирование и отладка включают в себя:
синтаксическую отладку;
отладку семантики и логической структуры программы;
тестовые расчеты и анализ результатов тестирования;
попутное совершенствование программы.
Проверка в нормальных условиях
Проверка в экстремальных условиях
Проверка в исключительных ситуациях.
Что произойдет, если программе, не рассчитанной на обработку отрицательных и нулевых значений переменных, в результате какой-либо ошибки придется иметь дело как раз с такими данными?
Как будет вести себя программа, работающая с массивами, если количество их элементов превысит величину, указанную в объявлении массива?
Что произойдет, если числа будут слишком малыми или слишком большими?
Отправка решения на проверку, проведение расчетов, анализ и проверка полученных результатов.
Анализ различных способов решения учащимися поставленной задачи, обоснование выбора наиболее эффективного метода реализации решения задачи с помощью программных средств образовательного назначения.