Hosted by uCoz

Задача № 37. Проверить, является ли натуральное число счастливым билетом

Формулировка. Дано натуральное число 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 (в котором хранится длина исходного числа) на нечетность, и если оно нечетно, отбрасывает последнюю его цифру.

Далее необходимо накопить сумму цифр левой половины числа и вывести на экран результат сравнения сумм левой и правой половины.

Код:

  1. program HappyTicket;
  2. var
  3. n, a: longint;
  4. left, right, digits, i: byte;
  5. begin
  6. readln(n);
  7. a := n;
  8. digits := 0;
  9. while a <> 0 do begin
  10. a := a div 10;
  11. inc(digits)
  12. end;
  13. left := 0;
  14. right := 0;
  15. for i := 1 to digits div 2 do begin
  16. right := right + n mod 10;
  17. n := n div 10
  18. end;
  19. if odd(digits) then n := n div 10;
  20. for i := 1 to digits div 2 do begin
  21. left:= left + n mod 10;
  22. n := n div 10
  23. end;
  24. writeln(left = right)
  25. 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).