Школа программиста

Забыли пароль?
[задачи] [курсы] [олимпиады] [регистрация]
Логин:   Пароль:    
Скрыть меню
О школе
Правила
Олимпиады
Фотоальбом
Гостевая
Форум
Архив олимпиад
Архив задач
Состояние системы
Рейтинг
Курсы
Новичкам
Работа в системе
Курсы ККДП
Дистрибутивы
Статьи
Ссылки


 

Неправильное сложение

(Время: 1 сек. Память: 16 Мб Сложность: 41%)

Для решения этой задачи удобно реализовать функцию, выполняющую "неправильное" сложение. После чего следует перебрать всевозможные варианты, которые могут получаться в результате вариации порядка сложения. Заметим, что несмотря на то, что данная операция неассоциативна, она коммутативна, т.е. a+b=b+a, поэтому мы получаем всего 3 возможных варианта сложения таких чисел: a+(b+c), b+(a+c) и c+(a+b). После чего следует отсортировать полученные числа и вывести соответствующий результат.

Возникает вопрос: в каком виде следует хранить и обрабатывать данные числа? Здесь возможно несколько вариантов:

  1. использовать для этого целый тип int64 (максимально возможное значение, которое может быть получено помещается в этом типе);
  2. хранить числа в виде строк;
  3. использовать целочисленный массив цифр.

В плане реализации более надежно и легко хранить числа как строки, это позволит легко и просто выполнять необходимые операции сложения и сравнения. Для простоты удобно ввести каноническую форму такого числа, которое всегда будет иметь одинаковое количество цифр: можно добавлять всегда число нулями слева до одной и той же длины (например, 20) и убирать лишние нули, если таковых излишне много. Для этого можно описать некоторую функцию Trim(s), которая будет возвращать канонический вид числа в виде строки одинаковой длины. Тогда сравнение чисел равносильно сравнению строк, а сложение можно выполнять поциферно, реализация такого сложения гораздо проще обычного сложения, используемого в длинной арифметике. Плюсом такой идеи так же является то, что подобная задача может быть решена для больших чисел.

Наиболее коротким и эффективным решением по времени выполнения (в данной задаче этим можно пренебречь) является реализация данной задачи с использованием типа int64 для хранения и обработки чисел. Единственным минусом здесь является наибольшая вероятность совершения ошибки в процессе реализации (по отношению к реализации той же программы в случае работы с числами как со строками). Приведем одну из возможных реализаций функции, реализующие сложение двух чисел типа int64 по нашим правилам:

  int64 sum(a,b){
    s=0; d=1;
    while(a+b>0){
      x = a mod 10 + b mod 10;
      s = s + d*x;
      a = a div 10;
      b = b div 10;
      while(d<=s) d=d*10;
      if(x=0) d=d*10;
    }
    return s;
  }

Используя данную функцию, алгоритмическая реализация основной части программы достаточно проста и понятна:

  read(a,b,c);
  s[0]=0;
  s[1]=sum(a,sum(b,c));
  s[2]=sum(b,sum(a,c));
  s[3]=sum(c,sum(a,b));
  sort(s);
  if(s[1]=s[3]) writeln('NO'); else writeln('YES');
  for i=1..3
    if(s[i]>s[i-1]) writeln(s[i]);

[Обсуждение] [Все попытки] [Задача]


Красноярский краевой Дворец пионеров, (c)2006 - 2026, ИНН 246305493507, E-mail: admin@acmp.ru