Maximum number of characters using keystrokes A, Ctrl+A, Ctrl+C and Ctrl+V

前端 未结 14 1484
忘掉有多难
忘掉有多难 2020-12-07 07:03

This is an interview question from google. I am not able to solve it by myself. Can somebody shed some light?

Write a program to print the sequence of keystrokes suc

14条回答
  •  一整个雨季
    2020-12-07 07:25

    What follows uses the OP's second edit that pasting does not replace existing text.

    Notice a few things:

    • ^A and ^C can be considered a single action that takes two keystrokes, since it never makes sense to do them individually. In fact, we can replace all instances of ^A^C with ^K^V, where ^K is a one-key "cut" operation (let's abbreviate it X). We shall see that dealing with ^K is much nicer than the two-cost ^A^C.
    • Let's assume that an 'A' starts in the clipboard. Then ^V (let's abbreviate it Y) is strictly superior to A and we can drop the latter from all consideration. (In the actual problem, if the clipboard starts empty, in what follows we'll just replace Y with A instead of ^V up until the first X.)

    Every reasonable keystroke sequence can thus be interpreted as a group of Ys separated by Xs, for example YYYXYXYYXY. Denote by V(s) the number of 'A's produced by the sequence s. Then V(nXm) = V(n)*V(m), because X essentially replaces every Y in m with V(n) 'A's.

    The copy-paste problem is thus isomorphic to the following problem: "using m+1 numbers which sum to N-m, maximimze their product." For example, when N=6, the answer is m=1 and the numbers (2,3). 6 = 2*3 = V(YYXYYY) = V(AA^A^C^V^V) (or V(YYYXYY) = V(AAA^A^C^V). )

    We can make a few observations:

    For a fixed value of m, the numbers to choose are ceil( (N-m)/(m+1) ) and floor( (N-m)/(m+1) ) (in whatever combination makes the sum work out; more specifically you will need (N-m) % (m+1) ceils and the rest floors). This is because, for a < b, (a+1)*(b-1) >= a*b.

    Unfortunately I don't see an easy way to find the value of m. If this were my interview I would propose two solutions at this point:

    Option 1. Loop over all possible m. An O(n log n) solution.

    C++ code:

    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

    Option 2. Allow m to attain non-integer values and find its optimal value by taking the derivative of [(N-m)/(m+1)]^m with respect to m and solving for its root. There is no analytic solution, but the root can be found using e.g. Newton's method. Then use the floor and ceiling of that root for the value of m, and choose whichever is best.

提交回复
热议问题