キーストロークA、Ctrl + A、Ctrl + C、Ctrl + Vを使用した最大文字数


106

これはグーグルからのインタビューの質問です。一人で解決することはできません。誰かが光を当てることはできますか?

文字「A」の最大数を生成するように、キーストロークのシーケンスを出力するプログラムを作成します。あなたが唯一の4つのキーを使用することが許可されていますACtrl+ ACtrl+ CCtrl+ V。Nキーストロークのみが許可されます。すべてのCtrl+文字は1つのキーストロークと見なされるため、Ctrl+ Aは1つのキーストロークです。

たとえば、シーケンスACtrl+ ACtrl+ CCtrl+ Vは、4つのキーストロークで2つのAを生成します。

  • Ctrl + Aはすべて選択
  • Ctrl + Cはコピーです
  • Ctrl + Vは貼り付け

数学をしました。任意のNに対して、Aのx数、1 Ctrl+ A、1 Ctrl+ Cおよびy Ctrl+を使用してV、max((N-1)/ 2)2のA を生成できます。いくつかN> Mの場合、多くのように使用することをお勧めしますCtrl+ As「は、Ctrl+ CCtrl+ VシーケンスそれはAさんの数が2倍として。

シーケンスCtrl+ ACtrl+ VCtrl+ Cは既存の選択を上書きしません。選択したものにコピーした選択を追加します。


多くのテキストエディタで^Aは、通常「すべて選択」、^C「コピー」、^V「貼り付け」です。それはあなたにアイデアを与えますか?
ニコライフェティソフ2011年

「A」の数を意味します。たとえば、N = 7の場合、キーストロークA、A、A、CTRL + A、CTRL + C、CTRL + V、CTRL + Vを使用して9 Aを印刷できます
munda

ええと、それは7つのキーストロークです。
John Dibling

@John「すべてのCTRL +文字は1つのキーストロークと見なされるため、CTRL + Aは1つのキーストロークです。」
Fredley、2011年

1
私はC ++タグを削除しました。これは純粋にアルゴリズムの質問であり、うまくいけば、不幸なC ++フォロワーが投票に反対する/投票を終了するのを防ぐことができます。
Matthieu M.11年

回答:


43

動的プログラミングソリューションがあります。私たちは、0キーが0 Aになることを知って始めます。次にための貫通我々反復iまでのn二つのことをやって、:一度Aを押すと、すべての+のコピーを選択押しは、ペーストに続くj、実際に(回j-i-1以下;ここで注意トリックを:我々はなくて、それを複数回貼り付けることができますので、内容は、クリップボードにまだあります毎回コピー)。選択、コピー、貼り付けx 5は選択、コピー、貼り付け、選択、コピー、貼り付けと同等であり、クリップボードに多くを残すことができるため、後者の方が優れているため、最大4つの連続した貼り付けを検討するだけで済みます。に到達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] A1作成することを追加する必要がありj-i-1ます。これは、j-i-1最後の2行目で説明されています。

ここにいくつかの結果があります(n=> Aの数):

  • 7 => 9
  • 8 => 12
  • 9 => 16
  • 10 => 20
  • 100 => 1391569403904
  • 1,000 => 3268160001953743683783272702066311903448533894049486008426303248121757146615064636953144900245 174442911064952028008546304
  • 50,000 => 非常に大きな数です!

私は@SBに同意し、常に仮定を述べる必要があります。私の場合は、文字数を2倍にするために2回貼り付ける必要はありません。これは7の答えを得るので、私の解決策が間違っていない限り、仮定は正しいはずです。

私は、フォームのシーケンスをチェックしていないよ、なぜケースの誰かの不思議でCtrl+ ACtrl+ CACtrl+ V:最終結果は常に同じになりACtrl+ ACtrl+ CCtrl+ V私はどの考えます。


それはありますn => resultresult => n?いずれにせよ、それは間違っていると思います。7つのキーストロークで9 Asと入力できます。n => result間違いなら間違いです。入力できるとおりの数を未満にすることはできませんn
IVlad

@IVladですn => result。あなたは「私たちは7つのキーストロークで9 Asと入力できる」と言っています。「トリック」私はただで編集をお読みください。
moinudin

問題は、指定された数のAsを取得するためのキーストロークの最小数ではなく、指定された数のキーストロークに対するAsの最大数を見つけることです。
Andrew Clark、

1
@marcog-あなたの表記は少なくとも混乱し、多くても間違っています。nは、使用が許可されているキーストロークです。nキーストロークで入力できる数を計算する必要があります。したがって7 => 7、意味がありません。
IVlad

1
ルックスは右、+ 1は今、誰かがそれを降りることができるかどうかを見てみましょうO(n)かさえO(1):)。
IVlad

41

marcogのソリューションを使用して、で始まるパターンを見つけましたn=16。これを説明n=24するためにn=29、までのキーストロークを示します。読みやすくするために、^ AをS(選択)、^ CをC(コピー)、^ VをP(貼り付け)に置き換えました。

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の後、理想的なパターンは、選択、コピー、貼り付け、貼り付け、貼り付け、および繰り返しです。これにより、キーストローク5回ごとにAsの数に4が乗算されます。この5つのキーストロークパターンが残りのキーストロークを単独で消費できない場合は、4つのキーストロークパターン(SCPP)のいくつかが最後のキーストロークを消費し、必要に応じてSCPPPを置き換えます(またはペーストの1つを削除します)。4つのキーストロークパターンは、合計に4つのキーストロークごとに3を掛けたものです。

ここでこのパターンを使用すると、marcogのソリューションと同じ結果が得られるいくつかのPythonコードがありますが、O(1)です。これは、IVladが指摘してくれたことにより、べき乗により実際にはO(log n)です。

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 == 44があり、n % 5 == 13があり、n % 5 == 22があり、n % 5 == 31が存在し、そしてn % 5 == 40これは、に簡略化することができるあります(4 - n) % 5

e4の計算: パターンの合計数はn % 5 == 0、この数が正確にに増えることがわかったため、いつでも1ずつ増加しますn / 5。床の分割を使用すると、パターンの総数を取得できます。の総数は、パターンの総数e4からを引いたものe3です。Pythonに不慣れな方のために、//は、フロアディビジョンの将来を保証する表記法です。


1
良いですね!テスト済みで動作しn=3000ます。おそらく正しいでしょう。(残念ですが、今日投票できません:/)
moinudin

5
+1、とてもいい。マイナーニッピック:ただしO(1)、累乗は一定の時間内に実行できないため、実際にはそうではありません。ですO(log n)
IVlad

2
実際、シーケンス 'SCPPP'は文字数に3を掛けるだけです。最初の貼り付けは選択したテキストを上書きするだけです。
Nick Johnson

4
@Nick質問の最後の行:「シーケンスCtrl + A、Ctrl + V、Ctrl + Cは既存の選択を上書きしません。コピーした選択を選択した選択に追加します。」
モイヌディン2011年

2
@marcogはい、気づきませんでした。ただし、そのような動作をするOSについては知りません。
Nick Johnson

15

これが私がそれに取り組む方法です:

  • 仮定CtrlA=すべてを選択
  • 仮定CtrlC=コピーの選択
  • 仮定CtrlV=コピーした選択を貼り付け

テキストが与えられた場合、それを複製するには4回のキーストロークが必要です。

  • CtrlA それをすべて選択する
  • CtrlC それをコピーする
  • CtrlV 貼り付けます(これは選択範囲の上に貼り付けられます-仮定を述べてください)
  • CtrlV もう一度貼り付けると、2倍になります。

そこから、4 Aまたは5 Aを実行してから、上記をループすることを検討できます。ctrl + a, c, v, vループすると、テキストが指数関数的に増加することに注意してください。残りのストロークが4未満の場合は、CtrlV

Googleなどの場所でのインタビューの鍵は、想定を述べ、考えを伝えることです。彼らはあなたが問題を解決する方法を知りたいです。


6
面接テクニックの良い点は、正しい答えを得ることは、最終的に明確にコミュニケーションすることよりも重要ではないことです。
フレドリー、2011年

2
いい答えだ。:アルゴリズム、貪欲オフによって、2つのエラーのためにACVV-VVVVV7によって乗算し、ACVV-ACVV-V残りのストローク6.だからはCtrl-Vによる乗算<6の代わりに4
マルセルJackwerth

5

O(1)で解決可能:フィボナッチ数と同様に、印刷されたAs(およびキーストロークのシーケンス)の数を計算する式があります。


1)問題の説明を簡略化できます。

  • [A]、[Ca] + [Cc]、[Cv]のみと空のコピー/貼り付けバッファ

等しい

  • コピー・ペースト・バッファーに[Ca] + [Cc]、[Cv]および "A"のみが含まれている。

2)キーストロークのシーケンスは、{'*'、 'V'、 'v'}からN文字の文字列として記述できます。ここで、 'v'は[Cv]を意味し、 '*'は[Ca]と 'Vを意味します'は[Cc]を意味します。例:「vvvv * Vvvvv * Vvvv」

その文字列の長さはNと同じです。

そのストリング内のVvワードの長さの積は、生成されたAsの数と等しくなります。


3)その文字列の固定長Nと固定数Kの単語の場合、すべての単語の長さがほぼ等しい場合、結果は最大になります。ペアごとの差は±1以下です。

ここで、Nが指定されている場合、最適な数Kは何ですか?


4)長さLの単一の単語を1つ追加して単語数を増やしたい場合は、前の単語のL + 1倍に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)長さ4の多数の単語を含む文字列を生成するのに十分な大きさのNがあると仮定しますが、いくつかのキーストロークが残っています。それらをどのように使用すべきですか?

  • 残りが5個以上の場合:長さ4の別の単語を追加します。

  • 残りが0の場合:完了。

  • 4つ残っている場合:次のいずれか

    a)長さ3の単語を1つ追加します:4 * 4 * 4 * 4 * 3 = 768。

    b)または、4ワードを5に増やす:5 * 5 * 5 * 5 = 625。=> 1つの単語を追加することをお勧めします。

  • 残りが3つである場合:

    a)または、前の単語を長さ4から3に調整して、長さ3の単語を1つ追加します。4* 4 * 4 * 2 = 128 <4 * 4 * 3 * 3 = 144。

    b)3ワードを長さ5に増やします:5 * 5 * 5 = 125。=> 1つの単語を追加することをお勧めします。

  • 2つ残っている場合:次のいずれか

    a)または、長さ4から3に前の2つの単語を調整して、長さ3の1つの単語を追加します。4* 4 * 1 = 16 <3 * 3 * 3 = 27。

    b)2ワードを長さ5に増やします:5 * 5 = 25。=> 1つの単語を追加することをお勧めします。

  • 残りが1つである場合:

    a)または、長さ3の1つの単語を、長さ4から3に前の3つの単語を調整して追加します。4* 4 * 4 * 0 = 0 <3 * 3 * 3 * 3 = 81。

    b)1単語を5の長さに増やします:4 * 4 * 5 = 80。=> 1つの単語を追加することをお勧めします。


6)では、5)のルールを使用するための「十分な大きさのN」がない場合はどうなりますか?可能であれば、プランb)を守る必要があります。小さい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)ここで、長さNの文字列内の単語の最適な数Kは何ですか?

N <7の場合はK = 1、6 <N <11の場合はK = 2です。それ以外の場合:K = ceil((N + 1)/ 5)

C / 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}になります。


正しいようです、@ Andrewの回答で示されている例では機能しますが、あなたの回答もO(1)ではなくO(log N)ですよね?
rsenna、2011年

どうしてO(log N)になりますか?Asの数を計算する数式はO(1)で計算されます。キーストロークを印刷するアルゴリズムは、印刷するO(N)キーストロークがあるためO(N)か、正規表現として印刷できるO(1)のいずれかです。
コモナード、2011年

4の指数はNと共に増加するため、指数の計算はO(log N)です。因数分解された形式でAsの数を出力すると、O(1)になります。
Andrew Clark

あ、そう。整数演算で実際に数値を計算することを考えたことはありません。計算式または浮動小数点近似のどちらかにのみ関心があります。もちろん、他の数値と比較できるようにするには、正確に計算する必要があります。
コモナード、2011年

5

CtrlA+ CtrlC+ を使用CtrlVする利点は、4つの 'A'の後でのみです。

だから私はこのようなことをします(あなたが適切な言語を指定していないので、疑似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's use them with simple CTRL-Vs
FOR I IN N1 TO N
    PRINT 'CTRL-V'
NEXT

編集する

  1. CtrlVメインループでシングルを使用することに戻ります。
  2. ここで私がやろうとしていることを説明するコメントをいくつか追加しました。
  3. 「最初の4つのA」ブロックの問題を修正しました。

@SB:最後の貼り付けだけにCTRL-Vを行っています。ちなみに、これはまさにあなたが答えで言ったことです。つまり、私たちは同じように考えるので、なぜあなたが私を批判しているのかわかりません。
rsenna

1
グーグルは、あなたが望むどのように書くべき適切な言語を決して指定しない。
Spooks

3

Asの数を2倍にするには、3回のキーストロークが必要です。3枚以上のAsがすでに印刷されている場合にのみ、2倍にしてください。最後に許可されたキーストロークをaにCtrlVして、できる限り大きい数を2倍にすることを確認したいので、それを調整するために、最初の3つのAsの後に余分なキーストロークを追加します。

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");
}

編集:

これはひどいです。私は完全に自分より先を行き、コピーごとに複数の貼り付けを検討しませんでした。

編集2:

十分なキーストロークがある場合は、3回貼り付けるのが最適だと思います。5つのキーストロークで、Asの数に4を掛けます。これは、4つのキーストロークを使用して3を掛けるよりも、6つのキーストロークを使用して5を掛けるよりも優れています。これを比較するには、各メソッドに同じ数のキーストロークを与え、それぞれが同時にサイクルを終了するように(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乗数が最適です。


2

クリップボードにx文字、テキスト領域にx文字があるとします。それを「状態x」と呼びましょう。

「貼り付け」を数回押します(m-1便宜上、それを示します)。次に「すべて選択」と「コピー」を押します。このシーケンスの後、「state m * x」になります。ここでは、合計m + 1回のキーストロークを無駄にしています。したがって、漸近的成長は(少なくとも)f^nf =のようなもの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回押すと、さらに3回のキーストロークでAの数を2倍にする機会を逃します。

最後に[貼り付け]を押す回数は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、...


2

以下では、貼り付けによって既存のテキストが置き換えられないというOPの2番目の編集を使用します。

いくつかのことに注意してください:

  • ^ Aと^ Cは、個別に行うのは意味がないため、2つのキーストロークを実行する単一のアクションと見なすことができます。実際、^ A ^ Cのすべてのインスタンスを^ K ^ Vに置き換えることができます。ここで、^ Kはワンキーの「カット」操作です(Xと省略しましょう)。^ Kの処理は2コストの^ A ^ Cよりもはるかに優れていることがわかります。
  • 'A'がクリップボードで始まると仮定しましょう。次に、^ V(Yと略記しましょう)はAよりも厳密に優れており、Aをすべての考慮から除外できます。(実際の問​​題では、クリップボードが空で始まる場合、以下では、最初のXまで、Yを^ VではなくAに置き換えるだけです。)

したがって、すべての妥当なキーストロークシーケンスは、Xで区切られたYのグループ、たとえばYYYXYXYYXYとして解釈できます。シーケンスsによって生成された「A」の数をV(s)で示します。次に、V(nXm)= V(n)* V(m)です。これは、Xが本質的にmのすべてのYをV(n)のAで置き換えるためです。

したがって、コピーと貼り付けの問題は次の問題と同型です。「合計がNmになるm + 1の数値を使用して、積を最大化する」。たとえば、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) )andですfloor( (N-m)/(m+1) )(合計がうまくいくようにする組み合わせでは、より具体的には(N-m) % (m+1) ceils、残りfloorのs が必要になります)。これがために、ためですa < b(a+1)*(b-1) >= a*b

残念ながら、の値を見つける簡単な方法はわかりませんm。これが私のインタビューである場合、この時点で2つの解決策を提案します。

オプション1.すべての可能なループm。O(n log n)ソリューション。

C ++コード:

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、どちらが最適かを選択します。


0
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];
}

0

これが私のアプローチと解決策です。

アプローチ:

実行できる操作は3つあります。

  1. キーストロークA -1文字「A」を出力します
  2. キーストローク(Ctrl-A)+(Ctrl-C) -本質的に何も出力しません。これらの2つのキーストロークは個別に意味がないため、1つの操作に組み合わせることができます。また、このキーストロークは、次の貼り付け操作の出力を設定します。
  3. キーストローク(Ctrl-V) -このキーストロークの出力は、実際には前の(2番目の)操作に依存するため、コードでそれを考慮する必要があります。

ここで、3つの異なる操作とそれぞれの出力を指定すると、これらの操作のすべての順列を実行する必要があります。


仮定:

現在、この問題の一部のバージョンでは、Ctrl + A-> Ctrl + C-> Ctrl + Vの一連のキーストロークにより、強調表示された選択が上書きされることが示されています。この仮定を考慮に入れるには、以下のソリューションに1行のコードを追加するだけで、ケース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;
}    

0

上記の答えで述べたトリックを使用すると、数学的には、ソリューションは次のように1つの方程式で説明できます。

4 + 4 ^ [(N-4)/ 5] +((N-4)%5)* 4 ^ [(N-4)/ 5]。ここで、[]は最大の整数係数です


0

mAを手動で印刷してから、Ctrl+ ACtrl+ C、およびNm-2 Ctrl+ を使用することの間にはトレードオフがありVます。最善の解決策は真ん中です。最大キーストローク= 10の場合、最良の解決策は5 Aまたは4 Aを入力することです。

これを試してみてくださいこのhttp://www.geeksforgeeks.org/how-to-print-maximum-number-of-a-using-given-four-keys/を見て、おそらく中盤あたりの結果を少し最適化して最適化してくださいポイント。


0

これは、ネストされたループのない動的プログラミングを使用した私のソリューションであり、入力する必要がある実際の文字も出力します。

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 

0

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になります。


StackOverflowへようこそ!コンテンツのフォーマットを追加する方法を学び、実際の矢印記号を使用することもできます。これにより、回答が読みやすくなります。
M. Mimpen 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.