Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package jsomeapp;
- import java.math.BigInteger;
- import java.util.HashSet;
- import java.util.Set;
- /**
- *
- * @author miceZipper
- */
- public class JSomeApp {
- Set<Entry> memory = new HashSet<>();
- static long interationsCalc = 0;
- static long interationsMemory = 0;
- static long usedMemory = 0;
- /**
- * @param args the command line arguments
- */
- public static void main(String[] args) {
- //Запускаем, собственно, метод подсчёта счастливых билетов. Заранее считаем, что мы ввели четное число. Проверять не будем.
- BigInteger sum = new JSomeApp().calc(50/*Integer.parseInt(args[0])*/);
- //Вывод результатов
- StringBuilder output = new StringBuilder();
- output.append("MEMORY: ").append(interationsMemory).append(" used: ").append(usedMemory).append("\n")
- .append("CALC: ").append(interationsCalc).append(" sum: ").append(sum.toString()).append("\n");
- System.out.println(output.toString());
- }
- public BigInteger calc(int length) {
- int maxValue = 9 * length / 2; //Берём половину разрядов и умножаем на максимальную цифру (9), чтобы получить максимальное значение суммы всех цифр, которую надо искать
- BigInteger sum = BigInteger.ZERO; //Инициализируем переменную результата, который мы ищем
- for (int i = 1; i <= maxValue; i++) { //Перебираем все искомые суммы от 1 до максимальной (9 * половину_кол-ва_цифр)
- BigInteger value = calc(i, length / 2); //Считаем кол-во комбинаций на текущую сумму
- sum = sum.add(value.pow(2)); //Добавляем к сумме квадрат количества комбинаций (чтобы учесть все комбинации с другой стороны тоже)
- }
- return sum.add(BigInteger.ONE); //Прибавляем 1, т.к. все нули (например 000000) - тоже счастливый билет
- }
- private BigInteger calc(long targetValue, int length) { //Входные параметры: количество разрядов (length) и искомую сумму (targetValue), для подсчета кол-ва комбинаций
- if (length == 1) { //Если длина = 1, то считаем, что если сумма меньше 10, то возвращаем 1 (совпадение), а если больше, то возвращаем 0 (совпадения нет)
- return targetValue < 10 ? BigInteger.valueOf(1) : BigInteger.valueOf(0);
- } else {
- for (Entry entry : memory) { //Ищем значение в памяти. Если нашли - возвращаем его.
- interationsMemory++;
- if (entry.length == length && entry.targetValue == targetValue) {
- usedMemory++;
- return entry.value;
- }
- }
- //Не нашли значение в памяти. Расчитываем его вручную
- BigInteger value = BigInteger.ZERO; //Инициализируем переменную суммы
- //Проходим по значениям разряда (по-очереди), в случае если искомая сумма меньше 10, то проходим до неё
- for (int i = 0; i <= (targetValue < 10 ? targetValue : 9); i++) {
- interationsCalc++;
- //Если дошли до искомой суммы, то добавляем в сумму 1 (т.к. дальше перебирать нет смысла), а если нет, то перебираем дальше, но уже на разряд ниже.
- value = value.add(i == targetValue ? BigInteger.ONE : calc(targetValue - i, length - 1));
- }
- memory.add(new Entry(length, targetValue, value));
- return value;
- }
- }
- private class Entry { //Класс для хранения рассчитанных данных
- int length;
- long targetValue;
- BigInteger value;
- public Entry(int length, long targetValue, BigInteger value) {
- this.length = length;
- this.targetValue = targetValue;
- this.value = value;
- }
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof Entry) {
- if (length == ((Entry) obj).length && targetValue == ((Entry) obj).targetValue) {
- return true;
- }
- }
- return false;
- }
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 37 * hash + this.length;
- hash = 37 * hash + (int) (this.targetValue ^ (this.targetValue >>> 32));
- return hash;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment