Написать программу для проверки попадания точки с производными координатами x,y в область плоскости , показанную штриховкой на рисунке. случай попадания на границу области выделяется особо. координаты точки вводятся в ручную
1) "лет" -если последняя цифра 0,5,6,7,8,9 или две цифры 05÷20
а остальные (не попавшие в первое условие) именуются так:
2) "год" -если последняя цифра 1
3) "года" -если последняя цифра 2,3,4
Вот несколько вариантов программы (проверял в PascalABC.NET 3.4.2.1837, и часть программ будет работать только там):
1) Вариант с самыми простыми и известными операторами (для начинающих и для совместимости с другими версиями Pascal). Поэтому: используются только if-then-else, составной оператор (блок) begin-end, операции сравнения, обычные ввод и вывод, и переменные типов integer и string; не используются логические операции. Правда, есть операции нахождения остатка от деления на 10 и на 100 (n mod 10 и n mod 100). Если вы их не проходили, то остаток можно вычислять, используя функции, возвращающие целую часть числа: n-Int(n/10)*10 и n-Int(n/100)*100 или n-Trunc(n/10)*10 и n-Trunc(n/100)*100. Всё это нужно для получения последней цифры числа (или двух последних цифр).
var
n: integer;
s: string;
begin
write('Введите возраст: ');
read(n);
if n < 0 then write('Недопустимый возраст.') else
if n > 120 then write('Недопустимый возраст.') else
begin
s := ' лет.';
if n mod 10 >= 2 then
if n mod 10 <= 4 then s := ' года.';
if n mod 10 = 1 then s := ' год.';
if n mod 100 >= 5 then
if n mod 100 <= 20 then s := ' лет.';
write('Вам ', n, s);
end;
end.
2) Вариант с использованием оператора выбора (case) и диапазонов значений. Я начинал с этого варианта, и тут я записал все диапазоны значений возраста до 120 лет (я не вспомнил общих правил написания лет-год-года в зависимости от количества лет, поэтому перебрал все возраста, проверяя написание на слух :)
Здесь и далее использована переменная типа byte (целые значения от 0 до 255, размер 1 байт). Если использовать тип integer, то по идее надо проверять на отрицательные значения, которые возможны при вводе для этого типа. Хотя, можно конечно считать, что вводить будут всегда правильно, и делать проще - не проверять это вообще (тогда пойдёт и integer). Если так упрощать, то можно не проверять и на возраст больше 120 лет.
Кроме byte, с той же целью можно использовать word (2 байта, 0..65535) или longword (4 байта, 0..4294967295), если вы их проходили. Правда, они слегка избыточны для этой задачи.
var n: byte;
begin
write('Введите возраст: ');
read(n);
case n of 0,5..20,25..30,35..40,45..50,55..60,65..70,75..80,85..90,95..100,105..120: write('Вам ',n,' лет.');
2а) В той же программе часть условий можно не писать (тут в проверке используется максимальное значение для типа byte, поэтому если менять тип, то нужно менять и это значение):
3) Тут остаток от деления на 10 проверяется на принадлежность к множеству указанных остатков. Ещё, есть логическая операция (or):
var n: byte;
begin
write('Введите возраст: ');
read(n);
if n>120 then write('Недопустимый возраст.') else
if (n mod 10 in [0,5..9]) or (n mod 100 in [5..20]) then write('Вам ',n,' лет.') else
if n mod 10 = 1 then write('Вам ',n,' год.') else write('Вам ',n,' года.')
end.
4) И напоследок, вариант с условной операцией (условие ? выражение1 : выражение2), конвертацией из строки в byte (и прочими непотребствами :) Лишние пробелы ужаты, поэтому всё не очень читаемо.
begin
var n:=byte.Parse(ReadString('Введите возраст:'));
write('Вам ',n>120?'многовато лет':n+' '+((n mod 10in[5..9,0])or(n mod 100in[5..20])?'лет':n mod 10=1?'год':'года'),'.')
end.
Отдельно, строка с выводом (более читаемо, без ужатия пробелов):
write('Вам ', n>120 ? 'многовато лет' : n + ' ' + ((n mod 10 in [5..9,0]) or (n mod 100 in [5..20]) ? 'лет' : n mod 10 = 1 ? 'год' : 'года'), '.')
Хотя, если перенести пробел и точку в сами сообщения, то строка даже чуть короче станет:
write('Вам ', n>120 ? 'многовато лет.' : n + ((n mod 10 in [5..9,0]) or (n mod 100 in [5..20]) ? ' лет.' : n mod 10 = 1 ? ' год.' : ' года.'))
Приведём все степени к основанию 2
2^3702-2^468+2^1620-108
-108 можно представить как -128 + 16 + 4
2^3702-2^468+2^1620-2^7 + 2^4 + 2^2
Теперь выстраиваем степени в порядке убывания:
2^3702+2^1620-2^468-2^7 + 2^4 + 2^2
В выражении два вычитания подряд, избавимся от этого, заменив -2^468 на -2^469 + 2^468
2^3702+2^1620 -2^469+2^468-2^7 + 2^4 + 2^2
2^3702 - 1 единица
2^4 - 1 единица
2^2 - 1 единица
Количество единиц в вычитаниях будет равно разнице степеней. Например 1000000-100=1111
2^1620 -2^469 - количеств единиц 1620-469 = 1151
2^468-2^7 - количество единиц 468-7 = 461
Общее количество единиц равно 3+1151+461 = 1615
Получается, зависит от последних цифр возраста:
1) "лет" -если последняя цифра 0,5,6,7,8,9 или две цифры 05÷20
а остальные (не попавшие в первое условие) именуются так:
2) "год" -если последняя цифра 1
3) "года" -если последняя цифра 2,3,4
Вот несколько вариантов программы (проверял в PascalABC.NET 3.4.2.1837, и часть программ будет работать только там):
1) Вариант с самыми простыми и известными операторами (для начинающих и для совместимости с другими версиями Pascal). Поэтому: используются только if-then-else, составной оператор (блок) begin-end, операции сравнения, обычные ввод и вывод, и переменные типов integer и string; не используются логические операции. Правда, есть операции нахождения остатка от деления на 10 и на 100 (n mod 10 и n mod 100). Если вы их не проходили, то остаток можно вычислять, используя функции, возвращающие целую часть числа: n-Int(n/10)*10 и n-Int(n/100)*100 или n-Trunc(n/10)*10 и n-Trunc(n/100)*100. Всё это нужно для получения последней цифры числа (или двух последних цифр).
var
n: integer;
s: string;
begin
write('Введите возраст: ');
read(n);
if n < 0 then write('Недопустимый возраст.') else
if n > 120 then write('Недопустимый возраст.') else
begin
s := ' лет.';
if n mod 10 >= 2 then
if n mod 10 <= 4 then s := ' года.';
if n mod 10 = 1 then s := ' год.';
if n mod 100 >= 5 then
if n mod 100 <= 20 then s := ' лет.';
write('Вам ', n, s);
end;
end.
2) Вариант с использованием оператора выбора (case) и диапазонов значений. Я начинал с этого варианта, и тут я записал все диапазоны значений возраста до 120 лет (я не вспомнил общих правил написания лет-год-года в зависимости от количества лет, поэтому перебрал все возраста, проверяя написание на слух :)
Здесь и далее использована переменная типа byte (целые значения от 0 до 255, размер 1 байт). Если использовать тип integer, то по идее надо проверять на отрицательные значения, которые возможны при вводе для этого типа. Хотя, можно конечно считать, что вводить будут всегда правильно, и делать проще - не проверять это вообще (тогда пойдёт и integer). Если так упрощать, то можно не проверять и на возраст больше 120 лет.
Кроме byte, с той же целью можно использовать word (2 байта, 0..65535) или longword (4 байта, 0..4294967295), если вы их проходили. Правда, они слегка избыточны для этой задачи.
var n: byte;
begin
write('Введите возраст: ');
read(n);
case n of 0,5..20,25..30,35..40,45..50,55..60,65..70,75..80,85..90,95..100,105..120: write('Вам ',n,' лет.');
1,21,31,41,51,61,71,81,91,101: write('Вам ',n,' год.');
2..4,22..24,32..34,42..44,52..54,62..64,72..74,82..84,92..94,102..104: write('Вам ',n,' года.');
else write('Недопустимый возраст.');
end;
end.
2а) В той же программе часть условий можно не писать (тут в проверке используется максимальное значение для типа byte, поэтому если менять тип, то нужно менять и это значение):
var n: byte;
begin
write('Введите возраст: ');
read(n);
case n of
121..255: write('Недопустимый возраст.');
1,21,31,41,51,61,71,81,91,101: write('Вам ',n,' год.');
2..4,22..24,32..34,42..44,52..54,62..64,72..74,82..84,92..94,102..104: write('Вам ',n,' года.');
else write('Вам ',n,' лет.');
end;
end.
3) Тут остаток от деления на 10 проверяется на принадлежность к множеству указанных остатков. Ещё, есть логическая операция (or):
var n: byte;
begin
write('Введите возраст: ');
read(n);
if n>120 then write('Недопустимый возраст.') else
if (n mod 10 in [0,5..9]) or (n mod 100 in [5..20]) then write('Вам ',n,' лет.') else
if n mod 10 = 1 then write('Вам ',n,' год.') else write('Вам ',n,' года.')
end.
4) И напоследок, вариант с условной операцией (условие ? выражение1 : выражение2), конвертацией из строки в byte (и прочими непотребствами :) Лишние пробелы ужаты, поэтому всё не очень читаемо.
begin
var n:=byte.Parse(ReadString('Введите возраст:'));
write('Вам ',n>120?'многовато лет':n+' '+((n mod 10in[5..9,0])or(n mod 100in[5..20])?'лет':n mod 10=1?'год':'года'),'.')
end.
Отдельно, строка с выводом (более читаемо, без ужатия пробелов):
write('Вам ', n>120 ? 'многовато лет' : n + ' ' + ((n mod 10 in [5..9,0]) or (n mod 100 in [5..20]) ? 'лет' : n mod 10 = 1 ? 'год' : 'года'), '.')
Хотя, если перенести пробел и точку в сами сообщения, то строка даже чуть короче станет:
write('Вам ', n>120 ? 'многовато лет.' : n + ((n mod 10 in [5..9,0]) or (n mod 100 in [5..20]) ? ' лет.' : n mod 10 = 1 ? ' год.' : ' года.'))