miceZipper

Счастливые билеты

Jun 28th, 2018
382
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.20 KB | None | 0 0
  1. package jsomeapp;
  2.  
  3. import java.math.BigInteger;
  4. import java.util.HashSet;
  5. import java.util.Set;
  6.  
  7. /**
  8.  *
  9.  * @author miceZipper
  10.  */
  11. public class JSomeApp {
  12.  
  13.     Set<Entry> memory = new HashSet<>();
  14.  
  15.     static long interationsCalc = 0;
  16.     static long interationsMemory = 0;
  17.     static long usedMemory = 0;
  18.  
  19.     /**
  20.      * @param args the command line arguments
  21.      */
  22.     public static void main(String[] args) {
  23.         //Запускаем, собственно, метод подсчёта счастливых билетов. Заранее считаем, что мы ввели четное число. Проверять не будем.
  24.         BigInteger sum = new JSomeApp().calc(50/*Integer.parseInt(args[0])*/);
  25.  
  26.         //Вывод результатов
  27.         StringBuilder output = new StringBuilder();
  28.         output.append("MEMORY: ").append(interationsMemory).append(" used: ").append(usedMemory).append("\n")
  29.                 .append("CALC: ").append(interationsCalc).append(" sum: ").append(sum.toString()).append("\n");
  30.         System.out.println(output.toString());
  31.  
  32.     }
  33.  
  34.     public BigInteger calc(int length) {
  35.         int maxValue = 9 * length / 2; //Берём половину разрядов и умножаем на максимальную цифру (9), чтобы получить максимальное значение суммы всех цифр, которую надо искать
  36.         BigInteger sum = BigInteger.ZERO; //Инициализируем переменную результата, который мы ищем
  37.         for (int i = 1; i <= maxValue; i++) { //Перебираем все искомые суммы от 1 до максимальной (9 * половину_кол-ва_цифр)
  38.             BigInteger value = calc(i, length / 2); //Считаем кол-во комбинаций на текущую сумму
  39.             sum = sum.add(value.pow(2)); //Добавляем к сумме квадрат количества комбинаций (чтобы учесть все комбинации с другой стороны тоже)
  40.         }
  41.         return sum.add(BigInteger.ONE); //Прибавляем 1, т.к. все нули (например 000000) - тоже счастливый билет
  42.     }
  43.  
  44.     private BigInteger calc(long targetValue, int length) { //Входные параметры: количество разрядов (length) и искомую сумму (targetValue), для подсчета кол-ва комбинаций
  45.         if (length == 1) { //Если длина = 1, то считаем, что если сумма меньше 10, то возвращаем 1 (совпадение), а если больше, то возвращаем 0 (совпадения нет)
  46.             return targetValue < 10 ? BigInteger.valueOf(1) : BigInteger.valueOf(0);
  47.         } else {
  48.             for (Entry entry : memory) { //Ищем значение в памяти. Если нашли - возвращаем его.
  49.                 interationsMemory++;
  50.                 if (entry.length == length && entry.targetValue == targetValue) {
  51.                     usedMemory++;
  52.                     return entry.value;
  53.                 }
  54.             }
  55.  
  56.             //Не нашли значение в памяти. Расчитываем его вручную
  57.             BigInteger value = BigInteger.ZERO; //Инициализируем переменную суммы
  58.            
  59.             //Проходим по значениям разряда (по-очереди), в случае если искомая сумма меньше 10, то проходим до неё
  60.             for (int i = 0; i <= (targetValue < 10 ? targetValue : 9); i++) {
  61.                 interationsCalc++;
  62.                 //Если дошли до искомой суммы, то добавляем в сумму 1 (т.к. дальше перебирать нет смысла), а если нет, то перебираем дальше, но уже на разряд ниже.
  63.                 value = value.add(i == targetValue ? BigInteger.ONE : calc(targetValue - i, length - 1));
  64.             }
  65.             memory.add(new Entry(length, targetValue, value));
  66.  
  67.             return value;
  68.         }
  69.  
  70.     }
  71.  
  72.     private class Entry { //Класс для хранения рассчитанных данных
  73.  
  74.         int length;
  75.         long targetValue;
  76.         BigInteger value;
  77.  
  78.         public Entry(int length, long targetValue, BigInteger value) {
  79.             this.length = length;
  80.             this.targetValue = targetValue;
  81.             this.value = value;
  82.         }
  83.  
  84.         @Override
  85.         public boolean equals(Object obj) {
  86.             if (obj instanceof Entry) {
  87.                 if (length == ((Entry) obj).length && targetValue == ((Entry) obj).targetValue) {
  88.                     return true;
  89.                 }
  90.             }
  91.             return false;
  92.         }
  93.  
  94.         @Override
  95.         public int hashCode() {
  96.             int hash = 7;
  97.             hash = 37 * hash + this.length;
  98.             hash = 37 * hash + (int) (this.targetValue ^ (this.targetValue >>> 32));
  99.             return hash;
  100.         }
  101.  
  102.     }
  103. }
Advertisement
Add Comment
Please, Sign In to add comment