Подтвердить что ты не робот

Максимальное количество символов с помощью клавиш A, Ctrl + A, Ctrl + C и Ctrl + V

Это вопрос интервью из Google. Я не могу решить это сам. Может кто-то пролил свет?

Напишите программу для печати последовательности нажатий клавиш так, чтобы она генерировала максимальное количество символов "A". Вам разрешено использовать только 4 клавиши: A, Ctrl + A, Ctrl + C и Ctrl + V. Разрешены только N нажатий клавиш. Все символы Ctrl + считаются одним нажатием клавиши, поэтому Ctrl + A является одним нажатием клавиши.

Например, последовательность A, Ctrl + A, Ctrl + C, Ctrl + V генерирует два A в 4 нажатиях клавиш.

  • Ctrl + A - Выбрать все
  • Ctrl + C - копирование
  • Ctrl + V - Вставить

Я сделал некоторую математику. Для любого N, используя x чисел A, один Ctrl + A, один Ctrl + C и y Ctrl + V, мы можем создать max ((N-1)/2) 2 количество A. Для некоторого N > M лучше использовать столько последовательностей Ctrl + A, Ctrl + C и Ctrl + V, сколько удваивает число A.

Последовательность Ctrl + A, Ctrl + V, Ctrl + C не перезапишет существующий выбор. Он добавит скопированный выбор к выбранному.

4b9b3361

Ответ 1

Там есть динамическое программирующее решение. Мы начинаем знать, что 0 клавиш могут сделать нас 0 A. Затем мы перебираем для i до n, делая две вещи: нажимая A один раз и нажимая select all + copy, а затем вставьте j times (на самом деле j-i-1 ниже), обратите внимание на трюк здесь: содержимое все еще в буфер обмена, чтобы мы могли вставлять его несколько раз без копирования каждый раз). Нам нужно рассмотреть только до четырех последовательных паст, поскольку выбор, копирование, вставка x 5 эквивалентно выбору, копированию, вставке, выбору, копированию, вставке, а последнее лучше, так как оно оставляет нам больше в буфере обмена. Как только мы достигнем n, мы получим желаемый результат.

Сложность может показаться O (N), но поскольку числа растут с экспоненциальной скоростью, это фактически O (N 2) из-за сложности умножения больших чисел. Ниже приведена реализация Python. Для вычисления N = 50 000 требуется около 0,5 секунды.

def max_chars(n):
  dp = [0] * (n+1)
  for i in xrange(n):
    dp[i+1] = max(dp[i+1], dp[i]+1) # press a
    for j in xrange(i+3, min(i+7, n+1)):
      dp[j] = max(dp[j], dp[i]*(j-i-1)) # press select all, copy, paste x (j-i-1)
  return dp[n]

В коде j отображается общее количество нажатых клавиш после нашей новой последовательности нажатий клавиш. На этом этапе у нас уже есть клавиши i, а 2 новых нажатия клавиш - для выбора и копирования. Поэтому мы нажимаем пасту j-i-2 раз. Поскольку вставка добавляет к существующей последовательности dp[i] A 's, нам нужно добавить 1, сделав ее j-i-1. Это объясняет j-i-1 во второй строке.

Вот некоторые результаты (n = > число A):

  • 7 = > 9
  • 8 = > 12
  • 9 = > 16
  • 10 = > 20
  • 100 = > 1391569403904
  • 1,000 = > 3268160001953743683783272702066311903448533894049486008426303248121757146615064636953144900245 174442911064952028008546304
  • 50,000 = > очень большое число!

Я согласен с @SB, что вы всегда должны указывать свои предположения: Mine заключается в том, что вам не нужно вставлять дважды, чтобы удвоить количество символов. Это получает ответ за 7, поэтому, если мое решение не так, предположение должно быть правильным.

Если кто-то задается вопросом, почему я не проверяю последовательности формы Ctrl + A, Ctrl + C, A, Ctrl + V: конечный результат всегда будет быть таким же, как A, Ctrl + A, Ctrl + C, Ctrl + V, который я считаю.

Ответ 2

Используя решение marcog, я нашел шаблон, начинающийся с n=16. Чтобы проиллюстрировать это, это клавиши для n=24 до n=29, я заменил ^ A на S (select), ^ C с C (копией) и ^ V с P (paste) для удобочитаемости:

24: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P
       4   *    4    *    4    *    4    *    4     = 1024
25: A,A,A,A,S,C,P,P,P,S,C,P,P,S,C,P,P,S,C,P,P,S,C,P,P
       4   *    4    *   3   *   3   *   3   *   3    = 1296
26: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,S,C,P,P,S,C,P,P
       4   *    4    *    4    *   3   *   3   *   3    = 1728
27: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,S,C,P,P
       4   *    4    *    4    *    4    *   3   *   3    = 2304
28: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P
       4   *    4    *    4    *    4    *    4    *   3    = 3072
29: A,A,A,A,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P,S,C,P,P,P
       4   *    4    *    4    *    4    *    4    *    4     = 4096

После первоначального 4 As идеальный паттерн - выбирать, копировать, вставлять, вставлять, вставлять и повторять. Это умножит число As на 4 каждые 5 нажатий клавиш. Если этот 5-тикратный шаблон не может использовать оставшиеся нажатия клавиш, некоторые из четырех комбинаций клавиш (SCPP) потребляют окончательные нажатия клавиш, заменяя SCPPP (или удаляя один из пасты) по мере необходимости. 4 рисунка нажатия клавиши умножают общее на 3 каждые 4 нажатия клавиш.

Использование этого шаблона здесь - это некоторый код Python, который получает те же результаты, что и решение marcog, но является O (1) edit. Это фактически O (log n) из-за возведения в степень, благодаря IVlad для указания этого.

def max_chars(n):
  if n <= 15:
    return (0, 1, 2, 3, 4, 5, 6, 9, 12, 16, 20, 27, 36, 48, 64, 81)[n]
  e3 = (4 - n) % 5
  e4 = n // 5 - e3
  return 4 * (4 ** e4) * (3 ** e3)

Вычисление e3: В конце списка нажатия клавиш всегда есть от 0 до 4 SCPP, для n % 5 == 4 - 4, n % 5 == 1 - 3, n % 5 == 2 - 2, n % 5 == 3 - 1 и n % 5 == 4 есть 0. Это можно упростить до (4 - n) % 5.

Вычисление e4: Общее число шаблонов увеличивается на 1 при n % 5 == 0, так как оказывается, что это число возрастает до точности n / 5. Используя разделение по полу, мы можем получить общее количество шаблонов, общее число для e4 - общее количество шаблонов минус e3. Для тех, кто не знаком с Python, // - это будущая нотация для разделения полов.

Ответ 3

Вот как я подойду к нему:

  • предположим Ctrl A= выбрать все
  • предположим Ctrl C= выбор копии
  • предположим Ctrl V= скопировать выделенную копию

с учетом некоторого текста, для его дублирования требуется 4 нажатия клавиш:

  • Ctrl A, чтобы выбрать все
  • Ctrl C, чтобы скопировать его
  • Ctrl V для вставки (это будет вставляться над выбором - СОСТОЯНИЕ ВАШИХ ПРЕДПОЛОЖЕНИЙ)
  • Ctrl V, чтобы снова вставить его, что удваивает его.

Оттуда вы можете рассмотреть возможность выполнения 4 или 5 A, а затем выполнить цикл выше. Обратите внимание, что выполнение ctrl + a, c, v, v будет увеличивать ваш текст экспоненциально по мере прохождения цикла. Если оставшиеся штрихи < 4, просто продолжайте делать Ctrl V

Ключ к интервью @таким местам, как Google, заключается в том, чтобы изложить свои предположения и сообщить свое мышление. они хотят знать, как вы решаете проблемы.

Ответ 4

Использование Ctrl A + Ctrl C + Ctrl V является преимуществом только после 4 'А.

Итак, я бы сделал что-то вроде этого (в псевдо-BASIC-коде, так как вы не указали какой-либо правильный язык):

// We should not use the clipboard for the first four A's:
FOR I IN 1 TO MIN(N, 4)
    PRINT 'CLICK A'
NEXT
LET N1 = N - 4

// Generates the maximum number of pastes allowed:
FOR I IN 1 TO (N1 DIV 3) DO
    PRINT 'CTRL-A'
    PRINT 'CTRL-C'
    PRINT 'CTRL-V'
    LET N1 = N1 - 3
NEXT

// If we still have same keystrokes left, let use them with simple CTRL-Vs
FOR I IN N1 TO N
    PRINT 'CTRL-V'
NEXT

Edit

  • Вернемся к использованию одного Ctrl V в основном цикле.
  • Добавлены комментарии для объяснения того, что я пытаюсь сделать здесь.
  • Исправлена ​​проблема с блоком "первые четыре A".

Ответ 5

Он доступен для решения в O (1): как и числа Фибоначчи, существует формула для вычисления количества печатных As (и последовательности нажатий клавиш):


1) Мы можем упростить описание проблемы:

  • Имея только [A], [C-a] + [C-c], [C-v] и пустой буфер копирования-вставки

равно

  • имеющий только [C-a] + [C-c], [C-v] и "A" в буфере copy-paste.

2) Мы можем описать последовательность нажатий клавиш как строку из N символов из {'*', 'V', 'v'}, где 'v' означает [Cv], а '*' означает [Ca] и 'V' означает [Cc]. Пример: "vvvv * Vvvvv * Vvvv"

Длина этой строки по-прежнему равна N.

Произведение длин Vv-слов в этой строке равно числу выпущенных As.


3) Учитывая фиксированную длину N для этой строки и фиксированное число K слов, результат будет максимальным, если все слова имеют почти равную длину. Их различие в паре не более ± 1.

Теперь, каково оптимальное число K, если N задано?


4) Предположим, мы хотим увеличить число слов, добавив одно слово длины L, тогда мы должны уменьшить L + 1 раз любое предыдущее слово на один 'v'. Пример: "... * Vvvv * Vvvv * Vvvv * Vvvv" → "... * Vvv * Vvv * Vvv * Vvv * Vvv"

Теперь, какова оптимальная длина слова L?

(5 * 5 * 5 * 5 * 5) (4 * 4 * 4 * 4 * 4) * 4, (4 * 4 * 4 * 4) > (3 * 3 * 3 * 3) * 3

= > Оптимальное значение L = 4.


5) Предположим, что у нас достаточно большого N для генерации строки со многими словами длиной 4, но осталось несколько нажатий клавиш; как их использовать?

  • Если осталось 5 или более левых: добавьте другое слово длиной 4.

  • Если осталось 0: Готово.

  • Если осталось 4: мы можем либо

    a) добавьте одно слово длиной 3: 4 * 4 * 4 * 4 * 3 = 768.

    b) или увеличить 4 слова до длины 5: 5 * 5 * 5 * 5 = 625. = > Добавление одного слова лучше.

  • Если осталось 3: мы можем либо

    a) или добавьте одно слово длиной 3, отрегулировав слово previus от длины 4 до 3: 4 * 4 * 4 * 2 = 128 < 4 * 4 * 3 * 3 = 144.

    b) увеличить 3 слова до длины 5: 5 * 5 * 5 = 125. = > Добавление одного слова лучше.

  • Если осталось 2: мы можем либо

    a) или добавьте одно слово длиной 3, отрегулировав два слова предыдущего с длиной от 4 до 3: 4 * 4 * 1 = 16 < 3 * 3 * 3 = 27.

    b) увеличить 2 слова до длины 5: 5 * 5 = 25. = > Добавление одного слова лучше.

  • Если осталось 1: мы можем либо

    a) или добавьте одно слово длиной 3, отрегулировав три слова трижды от длины 4 до 3: 4 * 4 * 4 * 0 = 0 < 3 * 3 * 3 * 3 = 81.

    b) увеличить одно слово до длины 5: 4 * 4 * 5 = 80. = > Добавление одного слова лучше.


6) Итак, что, если у нас нет "достаточного большого N" для использования правил в 5)? Мы должны придерживаться плана б), если это возможно! Строки для малых N:

1: "v", 2: "vv", 3: "vvv", 4: "vvvv"

5: "vvvvv" → 5 (план b)

6: "vvvvvv" → 6 (план b)

7: "vvv * Vvv" → 9 (план a)

8: "vvvv * Vvv" → 12 (план a)

9: "vvvv * Vvvv" → 16

10: "vvvv * Vvvvv" → 20 (план b)

11: "vvv * Vvv * Vvv" → 29 (план a)

12: "vvvv * Vvv * Vvv" → 36 (план a)

13: "vvvv * Vvvv * Vvv" → 48 (план a)

14: "vvvv * Vvvv * Vvvv" → 64

15: "vvv * Vvv * Vvv * Vvv" → 81 (план a)

...


7) Теперь, каково оптимальное число K слов в строке длины N?

Если N < 7, тогда K = 1 else, если 6 < N < 11, то K = 2; в противном случае: K = ceil ((N + 1)/5)

Написан на языке C/С++/Java: int K = (N<7)?(1) : (N<11)?(2) : ((N+5)/5);

И если N > 10, то число слов с длиной 3 будет: K * 5-1-N. При этом мы можем вычислить количество напечатанных As:

Если N > 10, число As будет: 4 ^ {N + 1-4K} · 3 ^ {5K-N-1}

Ответ 6

Требуется 3 нажатия клавиш, чтобы удвоить количество символов As. Имеет смысл начать удвоение, если у вас есть 3 или более Как уже напечатано. Вы хотите, чтобы ваше последнее нажатие клавиши было Ctrl V, чтобы убедиться, что вы удваиваете наибольшее количество, которое вы можете, поэтому, чтобы выровнять его, мы наполним любые дополнительные нажатия клавиш после первых трех. Как в начале с более В виде.

for (i = 3 + n%3; i>0 && n>0; n--, i--) {
    print("a");
}

for (; n>0; n = n-3) {
    print("ctrl-a");
    print("ctrl-c");
    print("ctrl-v");
}

Edit:

Это ужасно, я полностью опередил себя и не рассматривал несколько паст для каждой копии.

Изменить 2:

Я считаю, что вставка 3 раза оптимальна, когда у вас достаточно нажатий клавиш, чтобы сделать это. В 5 нажатиях клавиш вы умножаете свой номер As на 4. Это лучше, чем умножение на 3 с использованием 4 нажатий клавиш и лучше, чем умножение на 5 с использованием 6 нажатий клавиш. Я сравнивал это, предоставляя каждому методу такое же количество нажатий клавиш, что и каждый из них заканчивал цикл одновременно (60), позволяя 3-мультипликатору делать 15 циклов, 4-множитель делает 12 циклов, а 5- множитель выполняет 10 циклов. 3 ^ 15 = 14,348,907, 4 ^ 12 = 16,777,216 и 5 ^ 10 = 9,765,625. Если осталось всего 4 нажатия клавиш, выполнение 3-множителя лучше, чем склеивание еще 4 раза, по сути дела, что предыдущий 4-множитель станет 8-множителем. Если осталось всего 3 нажатия клавиш, лучше всего использовать 2-множитель.

Ответ 7

Предположим, что у вас есть символы x в буфере обмена и символы x в текстовой области; позвольте называть его "state x".

Позвольте несколько раз нажать "Вставить" (для удобства я обозначаю его m-1), затем "Выбрать все" и "Копировать"; после этой последовательности мы получаем "состояние m * x". Здесь мы потратили в общей сложности m + 1 нажатий клавиш. Таким образом, асимптотический рост есть (по крайней мере) нечто вроде f^n, где f = m^(1/(m+1)). Я считаю, что это максимально возможный асимптотический рост, хотя я не могу его доказать (пока).

Попытка различных значений m показывает, что максимум для f получается для m=4.

Можно использовать следующий алгоритм:

Press A a few times
Press Select-all
Press Copy
Repeat a few times:
    Press Paste
    Press Paste
    Press Paste
    Press Select-all
    Press Copy
While any keystrokes left:
    Press Paste

(не уверен, что он оптимальный).

Количество нажатий A в начале - 3: если вы нажмете 4 раза, вы упустите возможность удвоить число A еще на 3 нажатия клавиш.

Количество нажатий на кнопку Вставить в конце не более 5: если у вас осталось 6 или более нажатий клавиш, вы можете вместо этого использовать Вставить, Вставить, Вставить, Выбрать все, Копировать, Вставить.

Итак, мы получаем следующий алгоритм:

If (less than 6 keystrokes - special case)
    While (any keystrokes left)
        A
Else
    First 5 keystrokes: A, A, A, Select-all, Copy
    While (more than 5 keystrokes left)
        Paste, Paste, Paste, Select-all, Copy
    While (any keystrokes left)
        Paste

(не уверен, что он оптимальный). Число символов после выполнения этого похоже на

3 * pow(4, floor((n - 6) / 5)) * (2 + (n - 1) % 5).

Примеры значений: 1,2,3,4,5,6,9,12,15,18,24,36,48,60,72,96,144,192,240,288,...

Ответ 8

Далее следует второе редактирование OP, которое вставляет не существующий текст.

Обратите внимание на несколько вещей:

  • ^ A и ^ C можно рассматривать как одно действие, которое принимает два нажатия клавиш, так как никогда не имеет смысла делать их индивидуально. Фактически, мы можем заменить все экземпляры ^ A ^ C на ^ K ^ V, где ^ K - однократная "разрезанная" операция (пусть сокращает ее X). Мы увидим, что дело с ^ К намного лучше, чем двузначная ^ А ^ С.
  • Предположим, что в буфере обмена начинается "A". Тогда ^ V (пусть сокращенно Y) строго превосходит А, и мы можем отбросить последнее из всех соображений. (В реальной проблеме, если буфер обмена пуст, в дальнейшем мы просто заменим Y на A вместо ^ V вверх до первого X.)

Каждая разумная последовательность нажатия клавиш может быть интерпретирована как группа Ys, разделенная Xs, например YYYXYXYYXY. Обозначим через V (s) число "A, созданное последовательностью s. Тогда V (nXm) = V (n) * V (m), так как X существенно заменяет каждое Y в m на V (n) 'A.

Таким образом, проблема копирования-вставки изоморфна следующей задаче: "используя m + 1 чисел, которые суммируются с N-m, максимизируйте их произведение". Например, при N = 6 ответ равен m = 1 и числам (2,3). 6 = 2 * 3 = V (YYXYYY) = V (AA ^ A ^ C ^ V ^ V) (или V (YYYXYY) = V (AAA ^ A ^ C ^ V).)

Мы можем сделать несколько замечаний:

При фиксированном значении m номера, которые нужно выбрать, - это ceil( (N-m)/(m+1) ) и floor( (N-m)/(m+1) ) (в любой комбинации выработка суммы, более конкретно вам понадобится (N-m) % (m+1) ceils, а остальные floor > s). Это происходит потому, что для a < b, (a+1)*(b-1) >= a*b.

К сожалению, я не вижу простого способа найти значение m. Если бы это было мое интервью, я бы предложил два решения на данный момент:

Вариант 1. Переверните все возможные m. Решение O (n log n).

Код С++:

long long ipow(int a, int b)
{
  long long val=1;
  long long mul=a;

  while(b>0)
    {
      if(b%2)
    val *= mul;
      mul *= mul;
      b/=2;
    }
  return val;
}

long long trym(int N, int m)
{
  int floor = (N-m)/(m+1);
  int ceil = 1+floor;
  int numceils = (N-m)%(m+1);
  return ipow(floor, m+1-numceils) * ipow(ceil, numceils);
}

long long maxAs(int N)
{
  long long maxval=0;
  for(int m=0; m<N; m++)
    {
      maxval = std::max(maxval, trym(N,m));
    }
  return maxval;
}

Вариант 2. Разрешить m достичь нецелых значений и найти его оптимальное значение, взяв производную от [(N-m)/(m+1)]^m по отношению к m и решая ее корень. Аналитического решения нет, но корень можно найти, используя, например, Ньютона. Затем используйте пол и потолок этого корня для значения m и выберите то, что лучше.

Ответ 9

public int dp(int n) 
{
    int arr[] = new int[n];
    for (int i = 0; i < n; i++)
        arr[i] = i + 1;
    for (int i = 2; i < n - 3; i++) 
    {
        int numchars = arr[i] * 2;
        int j = i + 3;
        arr[j] = Math.max(arr[j], numchars);
        while (j < n - 1) 
        {
            numchars = numchars + arr[i];
            arr[++j] = Math.max(arr[j], numchars);
        }
    }
    return arr[n - 1];
}

Ответ 10

Вот мой подход и решение с кодом ниже.

Подход:

Можно выполнить три различных операции.

  • Нажатие клавиши A - выводит один символ 'A'
  • Нажатие клавиши (Ctrl-A) + (Ctrl-C) - ничего не выводит. Эти два нажатия клавиш могут быть объединены в одну операцию, потому что каждое из этих нажатий клавиш не имеет никакого смысла. Кроме того, это нажатие клавиши устанавливает выход для следующей операции вставки.
  • Нажатие клавиши (Ctrl-V) - вывод для этого нажатия клавиши действительно зависит от предыдущей (второй) операции, и, следовательно, нам нужно будет учитывать это в нашем коде.

Теперь, учитывая три разных операции и их соответствующие выходы, нам нужно выполнить все перестановки этих операций.


Предположение:

Теперь, в некоторой версии этой проблемы указано, что последовательность нажатий клавиш, Ctrl + A → Ctrl + C → Ctrl + V, перезаписывает выделенный выделен. Чтобы повлиять на это предположение, только одна строка кода должна быть добавлена ​​к решению ниже, где печатная переменная в случае 2 установлена ​​на 0

        case 2:
        //Ctrl-A and then Ctrl-C
            if((count+2) < maxKeys)
            {
                pOutput = printed;

                //comment the below statement to NOT factor 
                //in the assumption described above
                printed = 0;    
            }

Для этого решения

В приведенном ниже коде будет напечатано несколько последовательностей, и последняя последовательность будет правильным ответом для любого данного N. например. для N = 11 это будет правильная последовательность

С предположением

A, A, A, A, A, C, S, V, V, V, V,: 20:

Без предположения

A, A, A, C, S, V, V, C, S, V, V,: 27:

Я решил сохранить предположение для этого решения.


Обозначение клавиш:

'A' - A

'C' - Ctrl + A

'S' - Ctrl + C

'V' - Ctrl + V


Код:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void maxAprinted(int count, int maxKeys, int op, int printed, int pOutput, int *maxPrinted, char *seqArray)
{
    if(count > maxKeys)
        return;

    if(count == maxKeys)
    {
        if((*maxPrinted) < printed)
        {
            //new sequence found which is an improvement over last sequence
            (*maxPrinted) = printed;

            printf("\n");
            int i;
            for(i=0; i<maxKeys; i++)
                printf(" %c,",seqArray[i]);
        }

        return;
    }

    switch(op)
    {
        case 1:
        //A keystroke
            printed++;

            seqArray[count] = 'A';
            count++;
            break;

        case 2:
        //Ctrl-A and then Ctrl-C
            if((count+2) < maxKeys)
            {
                pOutput = printed;

                //comment the below statement to NOT factor 
                //in the assumption described above
                printed = 0;    
            }

            seqArray[count] = 'C';
            count++;
            seqArray[count] = 'S';
            count++;
            break;

        case 3:
        //Ctrl-V
            printed = printed + pOutput;

            seqArray[count] = 'V';
            count++;
            break;
    }

    maxAprinted(count, maxKeys, 1, printed, pOutput, maxPrinted, seqArray);
    maxAprinted(count, maxKeys, 2, printed, pOutput, maxPrinted, seqArray);
    maxAprinted(count, maxKeys, 3, printed, pOutput, maxPrinted, seqArray);    
}

int main()
{
    const int keyStrokes = 11;

    //this array stores the sequence of keystrokes
    char *sequence;
    sequence = (char*)malloc(sizeof(char)*(keyStrokes + 1));

    //stores the max count for As printed for a sqeuence
    //updated in the recursive call.
    int printedAs = 0;

    maxAprinted(0, keyStrokes,  1, 0, 0, &printedAs, sequence);

    printf(" :%d:", printedAs);

    return 0;
}    

Ответ 11

Используя трюки, упомянутые в ответах выше, математически Решение можно объяснить в одном уравнении, поскольку

4 + 4 ^ [(N-4)/5] + ((N-4)% 5) * 4 ^ [(N-4)/5]. где [] - наибольший целочисленный множитель

Ответ 12

Существует обмен между печатью m-A вручную, затем с использованием Ctrl + A, Ctrl + C и N-m-2 Ctrl + V. Лучшее решение находится посередине. Если максимальное нажатие клавиш = 10, лучшим решением является ввод 5 A или 4 A.

попробуйте использовать это. Посмотрите на http://www.geeksforgeeks.org/how-to-print-maximum-number-of-a-using-given-four-keys/ и, возможно, немного оптимизируйте результаты вокруг средней точки.

Ответ 13

Вот мое решение с динамическим программированием без вложенного цикла, которое также печатает фактические символы, которые вам нужно ввести:

N = 52

count = [0] * N
res = [[]] * N
clipboard = [0] * N

def maybe_update(i, new_count, new_res, new_clipboard):
  if new_count > count[i] or (
      new_count == count[i] and new_clipboard > clipboard[i]):
    count[i] = new_count
    res[i] = new_res
    clipboard[i] = new_clipboard

for i in range(1, N):
  # First option: type 'A'.
  # Using list concatenation for 'res' to avoid O(n^2) string concatenation.
  maybe_update(i, count[i - 1] + 1, res[i - 1] + ['A'], clipboard[i - 1])

  # Second option: type 'CTRL+V'.
  maybe_update(i, count[i - 1] + clipboard[i - 1],  res[i - 1] + ['v'],
               clipboard[i - 1])

  # Third option: type 'CTRL+A, CTRL+C, CTRL+V'.
  # Assumption: CTRL+V always appends.
  if i >= 3:
    maybe_update(i, 2 * count[i - 3],  res[i - 3] + ['acv'], count[i - 3])

for i in range(N):
  print '%2d %7d %6d %-52s' % (i, count[i], clipboard[i], ''.join(res[i]))

Это вывод ('a' означает 'CTRL + A' и т.д.)

 0       0      0                                                     
 1       1      0 A                                                   
 2       2      0 AA                                                  
 3       3      0 AAA                                                 
 4       4      0 AAAA                                                
 5       5      0 AAAAA                                               
 6       6      3 AAAacv                                              
 7       9      3 AAAacvv                                             
 8      12      3 AAAacvvv                                            
 9      15      3 AAAacvvvv                                           
10      18      9 AAAacvvacv                                          
11      27      9 AAAacvvacvv                                         
12      36      9 AAAacvvacvvv                                        
13      45      9 AAAacvvacvvvv                                       
14      54     27 AAAacvvacvvacv                                      
15      81     27 AAAacvvacvvacvv                                     
16     108     27 AAAacvvacvvacvvv                                    
17     135     27 AAAacvvacvvacvvvv                                   
18     162     81 AAAacvvacvvacvvacv                                  
19     243     81 AAAacvvacvvacvvacvv                                 
20     324     81 AAAacvvacvvacvvacvvv                                
21     405     81 AAAacvvacvvacvvacvvvv                               
22     486    243 AAAacvvacvvacvvacvvacv                              
23     729    243 AAAacvvacvvacvvacvvacvv                             
24     972    243 AAAacvvacvvacvvacvvacvvv                            
25    1215    243 AAAacvvacvvacvvacvvacvvvv                           
26    1458    729 AAAacvvacvvacvvacvvacvvacv                          
27    2187    729 AAAacvvacvvacvvacvvacvvacvv                         
28    2916    729 AAAacvvacvvacvvacvvacvvacvvv                        
29    3645    729 AAAacvvacvvacvvacvvacvvacvvvv                       
30    4374   2187 AAAacvvacvvacvvacvvacvvacvvacv                      
31    6561   2187 AAAacvvacvvacvvacvvacvvacvvacvv                     
32    8748   2187 AAAacvvacvvacvvacvvacvvacvvacvvv                    
33   10935   2187 AAAacvvacvvacvvacvvacvvacvvacvvvv                   
34   13122   6561 AAAacvvacvvacvvacvvacvvacvvacvvacv                  
35   19683   6561 AAAacvvacvvacvvacvvacvvacvvacvvacvv                 
36   26244   6561 AAAacvvacvvacvvacvvacvvacvvacvvacvvv                
37   32805   6561 AAAacvvacvvacvvacvvacvvacvvacvvacvvvv               
38   39366  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacv              
39   59049  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvv             
40   78732  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvv            
41   98415  19683 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvvv           
42  118098  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacv          
43  177147  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvv         
44  236196  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvv        
45  295245  59049 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvvv       
46  354294 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacv      
47  531441 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvv     
48  708588 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvv    
49  885735 177147 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvvv   
50 1062882 531441 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacv  
51 1594323 531441 AAAacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvvacvv 

Ответ 14

Если разрешены клавиши N, то результатом будет N-3.

A → N-3

CTRL + A → Выбор тех N символов: +1

CTRL + C → Копирование тех N символов: +1

CTRL + V → Вставка символов N.: +1 т.е. (поскольку мы выбрали целые символы, используя CTRL + A). Заменяя эти существующие символы N-3 на скопированные символы N-3 (который переопределяет одни и те же символы), а результат - N-3.