Формулировка. Дано натуральное число n. Проверить, является ли оно счастливым билетом.
Примечание: вообще, в математике обычно рассматриваются счастливые билеты с четным количеством цифр, потому что у них можно явно выделить левую и правую половины одинаковой длины, суммы цифр которых и сравниваются. Однако мы несколько расширим это определение, полагая, что если число имеет нечетную длину, его центральную цифру можно отбросить, так как ее логично было бы прибавить к накапливаемым суммам обоих половин, что, собственно, не изменит отношения между ними.
Например, число 14350 – счастливый билет, так как 1 + 4 = 5 + 0, а центральную цифру мы отбросили.
Решение. Задача является общим случаем задачи 10. Для ее решения необходимо знать длину числа (то есть его разрядность), вследствие чего нам необходимо скопировать переменную n в некоторую другую (например, a), чтобы на основе a посчитать количество десятичных разрядов n и сохранить его в некоторой переменной digits (digits в пер. с англ. означает «цифры»). Сделать это можно так:
a := n;
digits := 0;
while a <> 0 do begin
a := a div 10;
inc(digits)
end;
Здесь мы в каждой итерации цикла отбрасываем одну цифру от a и увеличиваем значение счетчика digits на 1. На некотором шаге число a будет однозначно и станет равным нулю при делении на 10, и после инкрементации счетчика, который теперь уже будет содержать количество цифр числа, произойдет выход из цикла.
Чтобы посчитать суммы левой и правой половины цифр числа (для накопления которых мы предусмотрим переменные leftи right), мы должны запустить два последовательных цикла от 1 до digits div 2, в которых прибавлять каждый полученный разряд к соответствующей переменной и отбрасывать его. Если длина нечетная, нам необходимо отбросить серединную цифру числа без прибавления к какой-либо сумме. Так как в первом цикле мы обработали и отбросили правую половину цифр числа, то по выходе из него серединная цифра как раз будет находиться в разряде единиц. Поэтому необходим следующий шаг:
if odd(digits) then n := n div 10;
Напомним, что функция odd(n) возвращает значение true, если n нечетно, и false, если n четно. То есть, написанный выше оператор проверяет счетчик digits (в котором хранится длина исходного числа) на нечетность, и если оно нечетно, отбрасывает последнюю его цифру.
Далее необходимо накопить сумму цифр левой половины числа и вывести на экран результат сравнения сумм левой и правой половины.
Код:
- program HappyTicket;
- var
- n, a: longint;
- left, right, digits, i: byte;
- begin
- readln(n);
- a := n;
- digits := 0;
- while a <> 0 do begin
- a := a div 10;
- inc(digits)
- end;
- left := 0;
- right := 0;
- for i := 1 to digits div 2 do begin
- right := right + n mod 10;
- n := n div 10
- end;
- if odd(digits) then n := n div 10;
- for i := 1 to digits div 2 do begin
- left:= left + n mod 10;
- n := n div 10
- end;
- writeln(left = right)
- end.
Представим, как должен работать алгоритм при вводе числа 14350:
1) Считаем длину числа, она равна 5 (строки 11-14);
2) В цикле из 5 div 2 = 2 повторений прибавляем к right крайние справа цифры 0 и 5, после чего отбрасываем их и имеем в n 143 (строки 17-20);
3) Так как odd(digits) = odd(5) = true, отбрасываем 3, после чего имеем в n 14 (строка 21);
4) В цикле из 5 div 2 = 2 повторений прибавляем к left оставшиеся цифры 1 и 4, после чего n становится равно 0, что, впрочем, нас уже не интересует (строки 22-25);
5) Выводим на экран значение выражения left = right – ответ положительный (строка 26).