Подсчет количества «ПЛОХИХ» значений

Я решал проблему и наткнулся на эту.

Предположим, у нас есть глиняные шарики. Каждый шар имеет определенное значение; значение каждого шара может быть любым положительным целым числом. Изначально для каждого значения от X до X+Y−1 (включительно) у нас есть бесконечный запас шаров с этими значениями.

У шаров есть особое свойство: любые два из них можно смешать, чтобы получился новый шар. Если исходные шары имели значения a и b (возможно, a=b), новый шар имеет значение a+b. Созданные таким образом шары можно использовать и для смешивания других шаров. Мы вольны смешивать шары любым способом, который выберем, и любое количество раз.

Назовем значение v (v>0) ПЛОХИМ, если нет возможности получить мяч со значением v; в противном случае значение v является ХОРОШИМ. Мы хотим сделать мячи со всеми ХОРОШИМИ значениями, и мы хотели бы знать количество ПЛОХИХ значений.

Примечание. Существует бесконечное количество ХОРОШИХ значений шаров, но можно доказать, что количество ПЛОХИХ значений всегда конечно для Y≥2.

Для заданных X и Y разработайте процедуру для нахождения количества значений BAD.

Например.

X = 1 ; Y = 2

Нам дарят [1, 1 + 2 - 1] == [1, 2] == {1, 2} мячей. Ответ 0 ; Так как можно получить шары со всеми возможными значениями по X и Y.

X = 3 ; Y = 3  

Нам дарят [3, 3 + 3 - 1] == [3, 5] == {3, 4, 5} мячей. Ответ 2 ; Поскольку шары со значениями 1 и 2 нельзя сделать.

Я думал, что значения меньше X нельзя сделать, но, похоже, это неправильно, может быть, я что-то упускаю.

Представьте, X = 11, Y = 2 вам даны шарики 11 и 12: вы не можете создать 13, 14, ...21, 25 и т. д.

Dmitry Bychenko 11.06.2019 09:20

Я не думаю, что количество плохих значений конечно. Если у вас есть два шара с четными номерами, скажем, 2 и 4, как вы получите шар с нечетным номером?

ChatterOne 11.06.2019 09:24

@ChatterOne: это невозможно: вам дается спектр, например. если X = 2, Y = 3 значит у тебя [2, 2 + 3 - 1] - {2, 3, 4} мячи

Dmitry Bychenko 11.06.2019 09:26

@DmitryBychenko О, я неправильно понял, что у вас просто два значения вместо диапазона. Хорошо, тогда.

ChatterOne 11.06.2019 09:27

@DmitryBychenko Теперь я понял, но как мы сможем посчитать эти значения?

Steve 11.06.2019 09:32

@Steve: При решении таких проблем начните с играть с цифрами, позвольте мне не предоставлять вам полное решение, но идея с 1st случаем (Y = 2) объяснена

Dmitry Bychenko 11.06.2019 09:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
125
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При решении таких задач начинайте с игра с цифрами. Допустим, нам дано 2 мячей (Y = 2), пусть это будут 11 и 12 (X = 11). Мы можем создать

  • Из 1 мяча: 11, 12
  • Из 2 шаров: 22, 23, 24
  • Из 3 шаров: 33, 34, 35, 36
  • Из 4 шаров: 44, 45, 46, 47, 48

....

Однако у нас есть отверстия (неверные числа): 1..10 размера 10, затем 13..21 размера 9, затем 25..32 размера 8. Можете ли вы увидеть образец? Сумма отверстий (количество неверных чисел) равна

10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 == 55

Теперь мы можем решить задачу, если Y = 2: это сумма артиметическая прогрессия

X - 1 + X - 2 + ... + 2 + 1 == (X - 1) * (X - 2) / 2 

Продолжайте делать Y = 3, например. нам дают 3 мячей (Y = 3) 11, 12, 13 (X = 11). Мы можем создать:

  • Из 1 мяча: 11, 12, 13
  • Из 2 шаров: 22, 23, 24, 25, 26
  • Из 3 шаров: 33, 34, 35, 36, 37, 38, 39
  • Из 4 шаров: 44, 45, 46, 47, 48, 49, 50, 51, 52

Давайте посчитаем отверстия: 1..10, затем 14..21, затем 26..33, а затем 40..43:

10 + 8 + 6 + 4 + 2 == 30

Можете ли вы увидеть образец? Можете ли вы решить для Y = 3? Пожалуйста, обратите внимание на разницу:

 X = 11; Y = 2   ->   10 + 9 + 8 + 7 + ... + 1
 X = 11; Y = 3   ->   10 + 8 + 6 + 4 + 2

Можешь сейчас написать формулу Y = 3? Для Y = 4, Y = 5?

 X = 11; Y = 4   ->   10 + 7 + 4 + 1
 x = 11; Y = 5   ->   10 + 6 + 2

Для произвольного Y?

 X = 11; Y       ->   10 + (10 - 1 * (Y - 1)) + (10 - 2 * (Y - 1)) + ...

Для произвольных X и Y (мы должны суммировать все члены положительный)?

 X; Y            ->   (X - 1) + (X - 1 - 1 * (Y - 1)) + (X - 1 - 2 * (Y - 1)) + ...

Код: Пусть будет С#:

private static int MySum(int X, int Y) {
  int d = Y - 1;                  // difference
  int n = (X - 1) / (Y - 1) + 1;  // number of items to sum

  int A1 = X - 1;                 // 1st item
  int An = X - 1 - (n - 1) * d;   // last item

  return (A1 + An) * n / 2;       // sum of arithmetic progression
}

Некоторые тесты (или демо):

(int, int)[] tests = new (int, int)[] {
   (X : 11, Y : 2),
   (X : 11, Y : 3),
   (X : 11, Y : 4),
   (X : 11, Y : 5),
   (X :  1, Y : 2),
   (X :  3, Y : 3),
};

string demo = string.Join(Environment.NewLine, tests
  .Select(test => $"X = {test.Item1,2}, Y = {test.Item2} => {MySum(test.Item1, test.Item2),2}"));

Console.Write(demo);

Исход:

X = 11, Y = 2 => 55
X = 11, Y = 3 => 30
X = 11, Y = 4 => 22
X = 11, Y = 5 => 18
X =  1, Y = 2 =>  0 // test from the question
X =  3, Y = 3 =>  2 // test from the question

Это так элегантно! Большое спасибо за объяснение.

Steve 11.06.2019 10:18

Не могли бы вы проверить stackoverflow.com/questions/56503879/…. Я попробовал реализацию в ответе, но в некоторых случаях это не удается.

Steve 11.06.2019 10:21

@Steve: максимизация суммы gcd кажется совсем другой проблемой; здесь у нас есть артиметическая прогрессия к сумме (a1 = X - 1, разность = Y - 1 и т. д.)

Dmitry Bychenko 11.06.2019 10:23

Я согласен, что это совершенно другая проблема, просто хотел немного разобраться в этом.

Steve 11.06.2019 10:24

Еще одно сомнение относительно того, как мы найдем «N», то есть количество терминов для использования суммы формулы AP? Sn = [n*(2*a + (n-1)*d)]/2

Steve 11.06.2019 14:03

@Steve: Ну, когда у нас есть прогресс, все детали кажутся довольно простыми. Хорошо, я добавил немного кода (C#) с тестами.

Dmitry Bychenko 11.06.2019 15:45

Этот код работает! Только для одного теста он не проходит, так как ввод X и Y имеет порядок 10 ^ 18, и нам нужно вычислить его по модулю 1000000007. Так что не могли бы вы помочь мне включить это в каждый промежуточный шаг, потому что если мы возьмите его в конце, он дает неправильный ответ.

Steve 12.06.2019 16:38

@Steve: измените int на BigInt или long, чтобы поддерживать диапазон до 1e18

Dmitry Bychenko 12.06.2019 17:26

Я использовал long int. Но им нужен ответ по модулю 1e9 + 7. Так что я ошибаюсь, беря по модулю на промежуточных шагах.

Steve 12.06.2019 17:54

@Steve: для вычисления по модулю в случае оператора С# поставить %. return (...) % 1000000007;

Dmitry Bychenko 12.06.2019 18:14

Это именно то, что я сделал! Тем не менее, это терпит неудачу для одного случая. Я немного почитал в Интернете, и там говорится, что для больших выражений мы должны взять% 1000000007 на промежуточных этапах, тогда он дает правильный ответ. (Распределительное свойство оператора mod.) Я взял по модулю промежуточные шаги, но дал неправильный ответ.

Steve 12.06.2019 18:36

@Steve: арифметика по модулю не так проста. Вероятно, лучший выход — вычислить результат через BigInteger, который может быть произвольно длинным, а затем вычислить остаток

Dmitry Bychenko 12.06.2019 18:57

BigInt - это ответ! Приняли наконец. Большое спасибо за помощь.

Steve 13.06.2019 15:55

Другие вопросы по теме