Сегодня, дорогой читатель, мы будем учиться писать программы. Я не буду рассказывать вам, как написать Notepad или что-нибудь подобное. Мы будем решать задачи подобные тем, которые решают в школах и институтах, а также на олимпиадах по информатике.
В МК было напечатано огромное количество статей по программированию. Часть из них просто описывала структуру и операторы языка, в других описывались некоторые приемы, используемые программерами, причем в визуальной среде разработки (типа Delphi или Visual Basic). Но начинать свою карьеру (или хобби) все же следует с изучения ДОСовских языков, например Паскаля (Pascal) или Бейсика (Basic). Я намерено не упомянул Си, так как он сложнее других языков программирования. Проще выучить тот же Паскаль, а с него перейти на Си.
Некоторые читатели заметят: «Как же так? Ведь в графической среде склепать программку намного легче и быстрее. Зачем нам учить какой-то Паскаль, который намного сложнее Delphi? И вообще, кому сейчас нужны проги под ДОС?» Так то оно так, но на самом деле Паскаль легче для начальных шагов. В нем вы узнаете основные принципы программирования, выучите алгоритмы, которые будете использовать в графической среде (для тех, кто не знает, что такое алгоритм, — это последовательность команд, выполнение которых позволяет получить ответ задачи).
Итак, приступим к первому заданию:
Задача № 1
Скорость автомобиля в любой момент определяется по формуле Vt=V0+GT, где V0 — начальная скорость, G — ускорение, T — время, а Vt — скорость в момент времени T. Составить программу, которая принимает с пульта V0 и G. Через какое время машина будет иметь скорость 100 км/час (то есть Vt = 100), если G>0? Через какое время машина остановится, если G<0?
Это одна из самых легких задач, но в ней есть один маленький подвох. Вот ее решение:
var v0, g: integer; // Объявляем переменные t: real; begin writeln('Input Vo and G:'); read(v0, g); // Ввод V0 и G if g > 0 then // Если G>0, то: begin t := (100 — v0)/g; // Находим Т по формуле writeln('Скорость будет равна 100km/h через', t, ' секунд'); // Выводим результат end; if g < 0 then // Если G<0, то: begin t := -v0/g; // Находим Т по формуле writeln('Автомобиль остановится через', t, ' секунд'); // Выводим результат end; if g = 0 then writeln('Скорость не изменится!'); // А вот и подвох :-). Скорость может и не меняться, о чем мы и сообщаем. end.
Мой вам совет: всегда, когда это возможно, решайте задачу в той же последовательности, что и в условии — это сэкономит кучу времени, так как вы никогда не перепутаете, что уже сделано, а что еще предстоит решить. Еще лучше записать все действия на листик бумаги и поочередно выполнять их, зачеркивая сделанные.
Простенькую задачку для разминки решили. Давайте сделаем что-то посложнее:
Задача № 2
Составить программу вывода всех трехзначных чисел, сумма цифр которых равна данному числу N. Число N должно быть целым, не превышать 27 и вводиться оператором INPUT.
Практически все задачи по программированию (кроме самых элементарных) можно решить несколькими способами, эта — не исключение. Цель программиста — не только решить задачу, но и решить ее оптимальным путем. Естественно, чтобы определить число, сумма цифр которого равна данному числу N, нужно эти цифры найти. Случается, что решающий переводит целочисленные трехзначные числа в строковой тип, потом вытягивает из него каждый знак и переводит их назад в целочисленный и только после этого находит их сумму. Это, конечно, правильно, но можно сделать и намного проще. Как? Смотрите решение:
var i, n, n1, n2, n3: integer; // Обьявляем переменные: n — число N; n1 (n2, n3) — первый (второй, третий) знак числа N. begin writeln('Введите целое N — от 1 до 27'); read(n); // Ввод числа N writeln; if (n < 1) or (n > 27) then // Проверяем, удовлетворяет ли введенное пользователем число условию begin writeln('Число N не удовлетворяет условию.'); halt; // Завершаем выполнение программы end; for i := 100 to 999 do // Перебираем все трехзначные числа begin n1 := Trunc(i/100); // Находим первый знак числа N n2 := Trunc((i-n1*100)/10); // Находим второй знак числа N n3 := i — (n1*100+n2*10); // Находим третий знак числа N if (n1+n2+n3) = n then write(i, ' '); // Вычисляем сумму всех знаков end; end.
Как я уже говорил, задачу можно решить по-разному. Вместо того, чтобы завершать выполнение программы, если N не удовлетворяет условию, вы можете, например, повторить его ввод.
Теперь давайте поподробнее рассмотрим алгоритм определения каждого знака трехзначного числа. Пусть, к примеру, переменная i будет равна 386. Вычисляем сначала первый знак (тройку): n1 := Trunc(386/100) — на сто делим потому, что искомый знак принадлежит разряду сотен, соответственно переменная n1 должна равняться 3.86; но функция Trunc отбрасывает дробную часть числа, поэтому n1 = 3. Первую цифру нашли, пора искать вторую (восьмерку). Она означает десятки, но если 386 поделить на 10, то получим не совсем то (точнее, совсем не то :-)), что хотели. Чтобы все получилось, нужно от 386 отнять 300, то есть первый знак умножить на сто (n1*100). Далее можно спокойно делить на 10, что мы и делаем: n2 := Trunc((i-n1*100)/10), не забывая при этом отбросить дробную часть. И самое простое — находим третью цифру. Для этого всего лишь отнимаем от 386 первый знак, умноженный на сто, и второй, умноженный на десять: n3 := i — (n1*100+n2*10). Все это в коде занимает только три строчки, в то время как ранее описанный метод — целых одиннадцать, то есть почти в четыре раза больше!
Ну что, поехали дальше? На сей раз нас ждет задача с массивами.
Задача № 3
Организовать линейный массив из 55 элементов. Заполнить случайными числами в интервале от 200 до 300. Вывести его в строку, напечатав рядом с наименьшим числом в скобках слово min и наибольшим —max. Например: 210 289 201(min) 275 … 298(max) 201(min).
Найти наименьшие и наибольшие числа несложно. Самый простой способ — найти их по ходу заполнения массива:
var mas: array[1..55] of integer; // Объявляем переменные i, min, max: integer; // min — хранит минимальное значение, max — максимальное begin Randomize; // Инициализируем генератор случайных чисел min := 300; // Присваиваем максимальновозможное значение переменной max := 200; // Присваиваем минимальновозможное значение переменной for i := 1 to 55 do begin mas[i] := Random(101) + 200; // Заполняем массив mas[i] if mas[i] < min then min := mas[i]; // Если значение mas[i] меньше min, то min равняется mas[i] if mas[i] > max then max := mas[i]; // Если mas[i] больше max, то max равняется mas[i] end; for i := 1 to 55 do begin write(' ', mas[i]); // Выводим массив на экран if mas[i] = min then write('(min) '); // Если значение массива минимальное, то пишем (min) if mas[i] = max then write('(max) '); // Если значение массива максимальное, то пишем (max) end; end.
Вот так решаются несложные задачки с массивами. На том и закончим наше занятие. Куда побежали? А домашнее задание?
Задача № 4
Каждый элемент таблицы A размерностью 3х3 может иметь значения 7, 8 и 9. Составить программу подсчета количества повторений каждого из этих чисел в таблице. Предполагается, что вначале идет блок заполнения данных по какому-либо закону.
Задание несложное, но если возникнут проблемы — пишите. Кстати, если вы знаете, как решить предыдущие задачи более оптимальным способом — тоже пишите. На следующем занятии я решу домашнее задание, а потом будем заниматься задачками посложнее. Смотрите, не прогуляйте урок :-).
(Продолжение следует)
