Вы потренируетесь выбирать счётчики и накопители, находить крайние значения вместе с их положением и проверять выполнение циклов по таблице трассировки. В конце разберёте, почему сравнение с квадратом номера повторения не определяет, является ли введённое число полным квадратом.
Упражнение 4.2.1 — Буквы в пароле
При регистрации на школьном сайте требуется пароль длины N. Не менее половины его символов должны быть латинскими буквами.
Напишите программу, которая считывает положительную длину N, а затем пароль посимвольно: каждый символ вводится на отдельной строке. Программа должна вывести количество латинских букв и сообщить, подходит ли пароль.
Учитывайте и заглавные буквы от 'A' до 'Z', и строчные от 'a' до 'z'.
Пример ввода:
6
D
6
v
7
U
2
Пример вывода:
Количество букв в пароле: 3
Пароль подходит
Проверьте также пароль нечётной длины. Например, при N = 5 двух букв недостаточно: как минимум половина означает не менее трёх букв. Подумайте, как проверить это без потери дробной части при целочисленном делении.
Упражнение 4.2.2 — Учёт собак
На ежегодной вакцинации в районе Шарон для каждой собаки вводят первую букву её имени, возраст в годах и обозначение категории:
R— породистая собака с документами;L— породистая собака без документов;M— собака смешанной породы.
Напишите программу, которая считывает данные 50 собак. Для каждой собаки выведите введённые данные, включая обозначение категории.
В конце выведите количество собак каждой категории и сообщите, какая категория встречалась чаще всего. Продумайте случай, когда несколько категорий имеют одинаковое наибольшее количество.
Упражнение 4.2.3 — Суммы цифр
Напишите программу, которая считывает 100 положительных четырёхзначных чисел. Для каждого числа выведите true, если сумма крайних цифр — тысяч и единиц — равна сумме средних цифр — сотен и десятков. Иначе выведите false.
Упражнение 4.2.4 — Загрязнение воздуха
Природоохранная организация установила допустимый уровень загрязнения воздуха в городе. Уровни выражаются положительными целыми числами. Каждый день выполняются два измерения; дневным показателем считается большее из них. Если измерения равны, дневной показатель равен этому значению.
Напишите программу, которая считывает допустимый уровень, а затем результаты двух измерений для каждого из 30 дней.
Программа должна:
- каждый день сообщать, превышает ли дневной показатель допустимый уровень;
- вывести номер дня с наибольшим дневным показателем;
- вывести номер дня с наименьшим дневным показателем.
Нумеруйте дни с 1. При равных крайних значениях укажите первый подходящий день.
Упражнение 4.2.5 — Метание копья
В соревновании участвовали семь человек. Для каждого участника известна дальность его броска.
Напишите программу, которая считывает семь расстояний и выводит:
- номер победителя по порядку ввода и дальность его броска;
- номер участника, занявшего последнее место, и дальность его броска;
- среднюю дальность семи бросков.
Нумеруйте участников с 1. Если одинаковую крайнюю дальность показали несколько участников, укажите первого из них.
Упражнение 4.2.6 — Сбор на переработку
68 учеников двух десятых классов собирают пластиковые бутылки и батарейки для переработки. За каждый предмет класс получает баллы:
- пластиковая бутылка — 3 балла;
- батарейка — 7 баллов.
Для каждого ученика вводятся номер класса (1 или 2), количество собранных бутылок и количество батареек. Если предметов этого вида нет, вводится 0.
Напишите программу, которая выведет общий результат каждого класса, затем номер победившего класса либо сообщение «Ничья».
Упражнение 4.2.7 — Трассировка вложенных условий
Проследите выполнение программы для следующего ввода слева направо. Первое число задаёт количество последующих чисел:
5, 13, 10, 20, 18, 25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int s = 0, n, a;
Console.WriteLine("Введите положительное целое число");
n = int.Parse(Console.ReadLine());
for (int i = 0; i < n; i++)
{
Console.WriteLine("Введите положительное целое число");
a = int.Parse(Console.ReadLine());
if (a > 10)
if (a >= 20)
Console.WriteLine("boom");
else
s = s + a;
}
Console.WriteLine(s); // (**)
- Составьте таблицу с колонками для всех переменных, каждого условия и вывода.
- Приведите пример ввода, при котором команда, отмеченная
(**), выведет0.
Проверка трассировки
После первого ввода n = 5, а s = 0. Перед каждой итерацией выводится приглашение ввести число. В таблице ниже колонка «Вывод тела» показывает дополнительный вывод после этого приглашения.
i |
n |
i < n |
a |
a > 10 |
a >= 20 |
s после тела |
Вывод тела |
|---|---|---|---|---|---|---|---|
| 0 | 5 | true |
13 | true |
false |
13 | — |
| 1 | 5 | true |
10 | false |
Не проверяется | 13 | — |
| 2 | 5 | true |
20 | true |
true |
13 | boom |
| 3 | 5 | true |
18 | true |
false |
31 | — |
| 4 | 5 | true |
25 | true |
true |
31 | boom |
| 5 | 5 | false |
25 | Не проверяется | Не проверяется | 31 | — |
После цикла выводится 31. Обратите внимание: else относится к ближайшему if (a >= 20), поэтому в сумму входят только числа строго больше 10 и строго меньше 20.
Пример для итогового вывода 0: 3, 10, 20, 25. Здесь n = 3, и ни одно из следующих чисел не попадает в диапазон от 11 до 19.
Упражнение 4.2.8 — Полный квадрат и ошибочная проверка
Полный квадрат — неотрицательное целое число, которое можно получить возведением целого числа в квадрат. Например, 16 — полный квадрат, потому что 4 * 4 = 16.
Часть 1. Объясните ошибку
Следующий код не подходит для определения всех полных квадратов:
1
2
3
4
5
6
7
8
9
10
11
12
int s = 0, num;
for (int i = 1; i <= 5; i++)
{
num = int.Parse(Console.ReadLine());
if (num == Math.Pow(i, 2))
{
s += num;
Console.WriteLine(num);
}
}
Console.WriteLine(s);
Объясните, в чём ошибка. Составьте таблицу трассировки для вводов 3, 4, 5, 16, 6, именно в этом порядке. Включите введённое число, i, Math.Pow(i, 2), результат сравнения и s после итерации.
Решение: подробная и сокращённая таблицы
Подробная таблица
Пустая ячейка означает, что на этом шаге значение не изменилось или команда не выполнялась.
| Строка кода | i |
num |
num == Math.Pow(i, 2) |
s |
Вывод |
|---|---|---|---|---|---|
| 1 | 0 | ||||
| 2–4 | 1 | 3 | |||
| 6 | false |
||||
| 2–4 | 2 | 4 | |||
| 6 | true |
||||
| 8–9 | 4 | 4 | |||
| 2–4 | 3 | 5 | |||
| 6 | false |
||||
| 2–4 | 4 | 16 | |||
| 6 | true |
||||
| 8–9 | 20 | 16 | |||
| 2–4 | 5 | 6 | |||
| 6 | false |
||||
2: последняя проверка i <= 5 |
6 | ||||
| 12 | 20 |
Сокращённая таблица
Можно объединить действия одной итерации в строку, если при этом видно, что изменилось и почему:
Ввод num |
i |
Math.Pow(i, 2) |
Результат сравнения | s после тела |
Вывод тела |
|---|---|---|---|---|---|
| 3 | 1 | 1 | false |
0 | — |
| 4 | 2 | 4 | true |
4 | 4 |
| 5 | 3 | 9 | false |
4 | — |
| 16 | 4 | 16 | true |
20 | 16 |
| 6 | 5 | 25 | false |
20 | — |
После цикла выводится итоговая сумма 20.
Почему алгоритм неверен
Код сравнивает каждый ввод только с одним квадратом — квадратом текущего i. Он проверяет не свойство числа, а совпадение числа с определённой позицией ввода.
Например, если первым ввести 9, то при i = 1 сравнение с Math.Pow(1, 2) даст false, хотя 9 = 3 * 3 — полный квадрат. Правильная проверка не должна зависеть от номера ввода.
Часть 2. Исправьте проверку
Напишите программу, которая генерирует десять целых чисел от 1 до 20 включительно и для каждого сообщает, является ли оно полным квадратом.
Создайте один объект Random перед циклом и используйте его для всех десяти чисел. Верхняя граница Next не включается, поэтому для диапазона от 1 до 20 нужна запись rnd.Next(1, 21).
Пример решения
Random rnd = new Random();
for (int i = 0; i < 10; i++)
{
int num = rnd.Next(1, 21);
int root = (int)Math.Sqrt(num);
if (root * root == num)
Console.WriteLine($"{num} — полный квадрат");
else
Console.WriteLine($"{num} — не полный квадрат");
}
Math.Sqrt возвращает квадратный корень. Приведение к int оставляет целую часть положительного результата. Проверка root * root == num определяет, восстанавливает ли эта целая часть исходное число. Для указанного небольшого диапазона это удобный способ проверки.