(18 intermediate revisions by the same user not shown)
Line 18: Line 18:
  
 
==={{Template:Author|Arjun Suresh|{{arjunweb}} }}===
 
==={{Template:Author|Arjun Suresh|{{arjunweb}} }}===
 +
A key to the solution is that we can continue pressing CTRL-V multiple times and the characters in the buffer will get printed continuously. The recurrence relation for the solution is
 +
 +
sol[n] = max(2 * sol[n-3], 3 * sol[n-4], 4 * sol[n-5]) | n > 6
 +
and
 +
1 for 1<= n <= 6
 +
 +
The recurrence relation is drawn from the fact that, the optimal solution at position $n$ will be obtained by CTRL-A, CTRL-C, CTRL-V sequence starting at either $(n-3)^{th}$  position or $(n-4)^{th}$ position or $(n-5)^{th}$ position. We needn't consider solution at position $(n-6)$ because that is already considered while calculating the solution at position $(n-3)$ which we are considering. Each CTRL-V prints the same number of characters as was on the screen during which the previous CTRL-A was typed. So, if we take $sol[n-3]$, that would mean CTRL-A starting at $n-2$, CTRL-C at $n-1$ and CTRL-V at $n$. So, $sol[n-3]$ is doubled at $n$. If we take $sol[n-4]$, there will be CTRL-V at positions $n-1$ and $n$, and so $sol[n]$ becomes $3$ times $sol[n-4]$. Similarly, if we take $sol[n-5]$, there will be 3 CTRL-V at $n-2$, $n-1$ and $n$ and $sol[n]$ becomes 4 times $sol[n-5]$.
  
 
<syntaxhighlight lang="c" name="printa">
 
<syntaxhighlight lang="c" name="printa">
 
#include <stdio.h>
 
#include <stdio.h>
#include <string.h>
+
 
 +
//Returns max of a,b,c
 +
int max(int a, int b, int c)
 +
{
 +
return a > b ? a > c? a:c : b > c? b:c;
 +
}
 +
 
 +
//Returns 1 if a = max(a,b,c), 2 if b = max(a,b,c) and 3 if c = max(a,b,c)
 +
int maxp(int a, int b, int c)
 +
{
 +
return a > b ? a > c? 1:3 : b > c? 2:3;
 +
}
 +
 
 +
void print(int *, int);
  
 
int main()
 
int main()
 
{
 
{
    unsigned int N, i, j;
+
unsigned int n, i;
    unsigned long long M;
+
unsigned long long sol[1000];
    unsigned long long sol[1000];
+
unsigned int prin[1000];
    unsigned long long buf[3];
+
printf("Enter N: ");
    unsigned int ind[1000];
+
scanf("%u", &n);
    printf("Enter N: ");
+
    scanf("%lu", &N);
+
for(i = 1 ;n>5? i<=5: i<= n; i++)
 
+
{
    unsigned long long arr[3];
+
sol[i] = i;
    memset(arr, 0, 3*sizeof(arr[0]));
+
prin[i] = 0;
    memset(sol, 0, 1000*sizeof(sol[0]));
+
}
    /*
+
if(n >= 6)
    arr[0] = 4;
+
{
    buf[0] = 1;
+
sol[6] = 6;
    arr[1] = 6;
+
prin[6] = 1;
    buf[1] = 2;
+
}
    arr[2] = 6;
+
for(i = 7; i <= n; i++)
    buf[2] = 3;
+
{
    */
+
sol[i] = max(2 * sol[i-3], 3 * sol[i-4], 4 * sol[i-5]);
    arr[0] = 4;
+
prin[i] = maxp(2 * sol[i-3], 3 * sol[i-4], 4 * sol[i-5]);
    buf[0] = 1;
+
}
    arr[1] = 6;
+
printf("M = %llu\n", sol[n]);
    buf[1] = 2;
+
printf("Enter any char to start printing the key sequence: \n");
    arr[2] = 6;
+
scanf("%d", &n);
    buf[2] = 3;
+
printf("Printing the sequence: \n\n");
    unsigned index;
+
print(prin, n);
    char * out[] = { "A\n", "CTRL+A\n", "CTRL+C\n", "CTRL+V\n"};
+
}
    unsigned int outf[1000];
+
 
    unsigned p = 2, pp = 3;
+
void print(int * prin, int n)
    memset(outf, 0, 1000*sizeof(outf[0]));
+
{
    for(i=1; i<=N; i++)
+
if(n < 1)
    {
+
return;
        if(i <= 6)
+
switch(prin[n])
        {
+
{
            outf[i] = 0;
+
case 0:
            sol[i] = i;
+
print(prin, n-1);
            ind[i] = 0;
+
printf("A\n");
            ind[6] = 3;
+
break;
           
+
case 1:
        }
+
print(prin, n-3);
       
+
printf("CTRL-A\nCTRL-C\nCTRL-V\n");
        else
+
break;
        {
+
case 2:
            printf("\n\ni = %u\n", i);
+
print(prin, n-4);
            arr[0] = arr[1] + buf[1];
+
printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\n");
            arr[1] = arr[2] + buf[2];
+
break;
            arr[2] = 2 * sol[i-3];
+
case 3:
            buf[0] = buf[1];
+
print(prin, n-5);
            buf[1] = buf[2];
+
printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\n");
            buf[2] = sol[i-3];
+
}
            if(arr[0] > arr[1])
+
}
            {
+
 
                if(arr[0] > arr[2])
+
</syntaxhighlight>
                {
+
 
                    index = i-5;
+
===Alternate Solution===
                    sol[i] = arr[0];
+
 
                   
+
The above solution assumes that after CTRL-C, we can do a mouse click as otherwise CTRL-V will override whatever was selected on the screen. If mouse click is not allowed, recurrence relation should be modified as:
                 
+
 
                  //  outf[i] = outf[i-1];
+
sol[n] = max(2 * sol[n-4], 3 * sol[n-5], 4 * sol[n-6], 5 * sol[n-7]) | n > 7
                    //outf[i-1] = outf[i-2];
+
and
                    if(p > 3){
+
1 for 1<= n <= 7
                    outf[p+1] = 1;
+
 
                    outf[p+2] = 2;
+
The code for this will be:
                    }
+
<syntaxhighlight lang="c" name="printa2">
                   
+
#include <stdio.h>
                  // for(j = 0; j < buf[0]; j++)
+
                    //  outf[j] = 0;
+
//Returns max of a,b,c,d
                    for(j = p+3; j <=i; j++)
+
int max(int a, int b, int c, int d)
                        outf[j] = 3;
+
{
                    ind[i] = p;
+
    return a > b ? a > c? a > d ? a : d : c > d? c : d  : b > c? b > d? b : d : c > d? c : d ;
                    if(ind[p] >= 3){
+
}
                    outf[ind[p]+1] = 1;
+
 
                    outf[ind[p]+2] = 2;
+
                    }
+
//Returns 1 if a = max(a,b,c,d), 2 if b = max(a,b,c,d), 3 if c = max(a,b,c,d) and 4 if d = max(a,b,c,d)
             
+
int maxp(int a, int b, int c, int d)
                    for(j = ind[p]+3; j <= p; j++)
+
{
                        outf[j] = 3;
+
    return a > b ? a > c? a > d ? 1 : 4 : c > d? 3 : 4 : b > c?  b > d? 2 : 4 : c > d? 3 : 4;
                 
+
}
                }
+
                else
+
void print(int *, int);
                {
+
                   
+
int main()
                    index = i-3;
+
{
                    sol[i] = arr[2];
+
unsigned int n, i;
                    outf[i] = 3;
+
unsigned long long sol[1000];
                 
+
unsigned int prin[1000];
                    outf[i-1] = 2;
+
printf("Enter N: ");
                    outf[i-2] = 1;
+
scanf("%u", &n);
                 
+
                    outf[i-1] = 2;
+
for(i = 1 ;n>7? i<=7: i<= n; i++)
                    outf[i-2] = 1;
+
{
                   
+
sol[i] = i;
                    ind[i] = i-3;
+
prin[i] = 0;
                    outf[ind[i-3]+1] = 1;
+
}
                    outf[ind[i-3]+2] = 2;
+
 
                    for(j = ind[i-3]+3; j < i-3; j++)
+
for(i = 8; i <= n; i++)
                    {
+
{
                        outf[j] = 3;
+
sol[i] = max(  2 * sol[i-4], 3 * sol[i-5], 4 * sol [i-6], 5 * sol[i-7]);
                    }
+
prin[i] = maxp(  2 * sol[i-4], 3 * sol[i-5], 4 * sol [i-6], 5 * sol[i-7]);
                  // p = pp;
+
}
                  // pp = i -3;
+
printf("M = %llu\n", sol[n]);
                  // printf("CTRL+A\nCTRL+C\nCTRL+V\n");
+
printf("Enter any char to start printing the key sequence: \n");
                }
+
scanf("%d", &n);
            }
+
printf("Printing the sequence: \n\n");
            else if (arr[1] > arr[2])
+
print(prin, n);
            {
+
}
                index = i-4;
+
                sol[i] = arr[1];
+
void print(int * prin, int n)
             
+
{
                outf[pp+1] = 1;
+
if(n < 1)
                outf[pp+2] = 2;
+
return;
             
+
switch(prin[n])
              // for(j = 0; j < buf[1]; j++)
+
{
                //       outf[j] = 0;
+
case 0:
                for(j = pp+3; j <=i; j++)
+
print(prin, n-1);
                    outf[j] = 3;
+
printf("A\n");
                ind[i] = pp;
+
break;
                if(ind[pp] >= 3){
+
case 1:
                outf[ind[pp]+1] = 1;
+
print(prin, n-4);
                outf[ind[pp]+2] = 2;
+
printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\n");
                }
+
break;
                for(j = ind[pp]+3; j <= pp; j++)
+
case 2:
                outf[j] = 3;
+
print(prin, n-5);
               
+
printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\nCTRL-V\n");
                //outf[i-1] = outf[i-2];
+
break;
                //outf[i-2]= outf[i-3];
+
case 3:
                //printf("CTRL+V\n");
+
print(prin, n-6);
            }
+
printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\nCTRL-V\nCTRL-V\n");
            else
+
                        break;
            {
+
                case 4:
             
+
            print(prin, n-7);
                index = i-3;
+
printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\nCTRL-V\nCTRL-V\nCTRL-V\n");
                sol[i] = arr[2];
+
}
                outf[i] = 3;
 
             
 
                outf[i-1] = 2;
 
                outf[i-2] = 1;
 
               
 
                ind[i] = i-3;
 
                outf[ind[i-3]+1] = 1;
 
                outf[ind[i-3]+2] = 2;
 
                for(j = ind[i-3]+3; j < i-3; j++)
 
                {
 
                    outf[j] = 3;
 
                }
 
                //p = pp;
 
              // pp = i -3;
 
             
 
                //printf("CTRL+A\nCTRL+C\nCTRL+V\n");
 
               
 
            }
 
         
 
          // sol[i] = max(arr[0] , arr[1], arr[2]);
 
       
 
            printf("\n%lld %lld %lld\n", arr[0], arr[1], arr[2]);
 
            printf("%lld %lld %lld\n", buf[0], buf[1], buf[2]);
 
            printf("p = %u pp = %u\n", p, pp);
 
            for(j = 1; j <= i; j++)
 
        {
 
           
 
        //    printf(out[outf[j]]);
 
        }
 
        p = pp;
 
            pp = i - 3;
 
        }
 
    }
 
    i = 1;
 
    while(i+1 < N && outf[i+1] != 2)
 
    {
 
        outf[i] = 0;
 
        i++;
 
    }
 
      printf("\n\nKey Sequences:\n\n");
 
    //  if(N <= 6)
 
      {
 
        //  printf("A\nA\nA\nA\nA\nA\n");
 
         
 
      }
 
      //else
 
      {
 
        for(i = 1; i <= N; i++)
 
        {
 
           
 
            printf(out[outf[i]]);
 
        }
 
      }
 
   
 
    for(i = 1; i <= N; i++)
 
        {
 
           
 
            printf("%u ",ind[i]);
 
        }
 
    printf("\nM = %llu\n", sol[N]);
 
   
 
 
}
 
}
  
Line 226: Line 185:
  
 
{{Template:FBD}}
 
{{Template:FBD}}
 +
 +
[[Category:Placement Coding Questions from Arrays]]

Latest revision as of 14:25, 23 July 2014

Imagine you have a special keyboard with the following keys:

A

Ctrl+A

Ctrl+C

Ctrl+V

where CTRL+A, CTRL+C, CTRL+V each acts as one function key for “Select All”, “Copy”, and “Paste” operations respectively.

If you can only press the keyboard for N times (with the above four keys), please write a program to produce maximum numbers of A. If possible, please also print out the sequence of keys. That is to say, the input parameter is N (No. of keys that you can press), the output is M (No. of As that you can produce).

Solution by Arjun Suresh

A key to the solution is that we can continue pressing CTRL-V multiple times and the characters in the buffer will get printed continuously. The recurrence relation for the solution is

sol[n] = max(2 * sol[n-3], 3 * sol[n-4], 4 * sol[n-5]) | n > 6 

and

1 for 1<= n <= 6

The recurrence relation is drawn from the fact that, the optimal solution at position $n$ will be obtained by CTRL-A, CTRL-C, CTRL-V sequence starting at either $(n-3)^{th}$ position or $(n-4)^{th}$ position or $(n-5)^{th}$ position. We needn't consider solution at position $(n-6)$ because that is already considered while calculating the solution at position $(n-3)$ which we are considering. Each CTRL-V prints the same number of characters as was on the screen during which the previous CTRL-A was typed. So, if we take $sol[n-3]$, that would mean CTRL-A starting at $n-2$, CTRL-C at $n-1$ and CTRL-V at $n$. So, $sol[n-3]$ is doubled at $n$. If we take $sol[n-4]$, there will be CTRL-V at positions $n-1$ and $n$, and so $sol[n]$ becomes $3$ times $sol[n-4]$. Similarly, if we take $sol[n-5]$, there will be 3 CTRL-V at $n-2$, $n-1$ and $n$ and $sol[n]$ becomes 4 times $sol[n-5]$.

<syntaxhighlight lang="c" name="printa">

  1. include <stdio.h>

//Returns max of a,b,c int max(int a, int b, int c) { return a > b ? a > c? a:c : b > c? b:c; }

//Returns 1 if a = max(a,b,c), 2 if b = max(a,b,c) and 3 if c = max(a,b,c) int maxp(int a, int b, int c) { return a > b ? a > c? 1:3 : b > c? 2:3; }

void print(int *, int);

int main() { unsigned int n, i; unsigned long long sol[1000]; unsigned int prin[1000]; printf("Enter N: "); scanf("%u", &n);

for(i = 1 ;n>5? i<=5: i<= n; i++) { sol[i] = i; prin[i] = 0; } if(n >= 6) { sol[6] = 6; prin[6] = 1; } for(i = 7; i <= n; i++) { sol[i] = max(2 * sol[i-3], 3 * sol[i-4], 4 * sol[i-5]); prin[i] = maxp(2 * sol[i-3], 3 * sol[i-4], 4 * sol[i-5]); } printf("M = %llu\n", sol[n]); printf("Enter any char to start printing the key sequence: \n"); scanf("%d", &n); printf("Printing the sequence: \n\n"); print(prin, n); }

void print(int * prin, int n) { if(n < 1) return; switch(prin[n]) { case 0: print(prin, n-1); printf("A\n"); break; case 1: print(prin, n-3); printf("CTRL-A\nCTRL-C\nCTRL-V\n"); break; case 2: print(prin, n-4); printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\n"); break; case 3: print(prin, n-5); printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\n"); } }

</syntaxhighlight>

Alternate Solution

The above solution assumes that after CTRL-C, we can do a mouse click as otherwise CTRL-V will override whatever was selected on the screen. If mouse click is not allowed, recurrence relation should be modified as:

sol[n] = max(2 * sol[n-4], 3 * sol[n-5], 4 * sol[n-6], 5 * sol[n-7]) | n > 7 

and

1 for 1<= n <= 7

The code for this will be: <syntaxhighlight lang="c" name="printa2">

  1. include <stdio.h>

//Returns max of a,b,c,d int max(int a, int b, int c, int d) {

   return a > b ? a > c? a > d ? a : d : c > d? c : d  : b > c? b > d? b : d : c > d? c : d ;

}


//Returns 1 if a = max(a,b,c,d), 2 if b = max(a,b,c,d), 3 if c = max(a,b,c,d) and 4 if d = max(a,b,c,d) int maxp(int a, int b, int c, int d) {

   return a > b ? a > c? a > d ? 1 : 4 : c > d? 3 : 4 : b > c?  b > d? 2 : 4 : c > d? 3 : 4;

}

void print(int *, int);

int main() { unsigned int n, i; unsigned long long sol[1000]; unsigned int prin[1000]; printf("Enter N: "); scanf("%u", &n);

for(i = 1 ;n>7? i<=7: i<= n; i++) { sol[i] = i; prin[i] = 0; }

for(i = 8; i <= n; i++) { sol[i] = max( 2 * sol[i-4], 3 * sol[i-5], 4 * sol [i-6], 5 * sol[i-7]); prin[i] = maxp( 2 * sol[i-4], 3 * sol[i-5], 4 * sol [i-6], 5 * sol[i-7]); } printf("M = %llu\n", sol[n]); printf("Enter any char to start printing the key sequence: \n"); scanf("%d", &n); printf("Printing the sequence: \n\n"); print(prin, n); }

void print(int * prin, int n) { if(n < 1) return; switch(prin[n]) { case 0: print(prin, n-1); printf("A\n"); break; case 1: print(prin, n-4); printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\n"); break; case 2: print(prin, n-5); printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\nCTRL-V\n"); break; case 3: print(prin, n-6); printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\nCTRL-V\nCTRL-V\n");

                       break;
               case 4: 
   		        print(prin, n-7);

printf("CTRL-A\nCTRL-C\nCTRL-V\nCTRL-V\nCTRL-V\nCTRL-V\nCTRL-V\n"); } }


</syntaxhighlight>




blog comments powered by Disqus

Imagine you have a special keyboard with the following keys:

A

Ctrl+A

Ctrl+C

Ctrl+V

where CTRL+A, CTRL+C, CTRL+V each acts as one function key for “Select All”, “Copy”, and “Paste” operations respectively.

If you can only press the keyboard for N times (with the above four keys), please write a program to produce maximum numbers of A. If possible, please also print out the sequence of keys. That is to say, the input parameter is N (No. of keys that you can press), the output is M (No. of As that you can produce).

Solution by Arjun Suresh[edit]

<syntaxhighlight lang="c" name="printa">

  1. include <stdio.h>
  2. include <string.h>

int main() {

   unsigned int N, i, j;
   unsigned long long M;
   unsigned long long sol[1000];
   unsigned long long buf[3];
   unsigned int ind[1000];
   printf("Enter N: ");
   scanf("%lu", &N);
 
   unsigned long long arr[3];
   memset(arr, 0, 3*sizeof(arr[0]));
   memset(sol, 0, 1000*sizeof(sol[0]));
   /*
   arr[0] = 4;
   buf[0] = 1;
   arr[1] = 6;
   buf[1] = 2;
   arr[2] = 6;
   buf[2] = 3;
   */
   arr[0] = 4;
   buf[0] = 1;
   arr[1] = 6;
   buf[1] = 2;
   arr[2] = 6;
   buf[2] = 3;
   unsigned index;
   char * out[] = { "A\n", "CTRL+A\n", "CTRL+C\n", "CTRL+V\n"};
   unsigned int outf[1000];
   unsigned p = 2, pp = 3; 
   memset(outf, 0, 1000*sizeof(outf[0]));
   for(i=1; i<=N; i++)
   {
       if(i <= 6)
       {
           outf[i] = 0;
           sol[i] = i;
           ind[i] = 0;
           ind[6] = 3;
           
       }
       
       else
       {
            printf("\n\ni = %u\n", i);
           arr[0] = arr[1] + buf[1];
           arr[1] = arr[2] + buf[2]; 
           arr[2] = 2 * sol[i-3];
           buf[0] = buf[1];
           buf[1] = buf[2];
           buf[2] = sol[i-3];
           if(arr[0] > arr[1])
           {
               if(arr[0] > arr[2])
               {
                   index = i-5;
                   sol[i] = arr[0];
                   
                 
                 //  outf[i] = outf[i-1];
                   //outf[i-1] = outf[i-2];
                   if(p > 3){
                   outf[p+1] = 1;
                   outf[p+2] = 2;
                   }
                   
                  // for(j = 0; j < buf[0]; j++)
                    //   outf[j] = 0;
                   for(j = p+3; j <=i; j++)
                       outf[j] = 3;
                   ind[i] = p;
                   if(ind[p] >= 3){
                   outf[ind[p]+1] = 1;
                   outf[ind[p]+2] = 2;
                   }
              
                   for(j = ind[p]+3; j <= p; j++)
                       outf[j] = 3;
                 
               }
               else
               {
                   
                   index = i-3;
                   sol[i] = arr[2];
                   outf[i] = 3;
                  
                   outf[i-1] = 2;
                   outf[i-2] = 1;
                  
                   outf[i-1] = 2;
                   outf[i-2] = 1;
                   
                   ind[i] = i-3;
                   outf[ind[i-3]+1] = 1;
                   outf[ind[i-3]+2] = 2;
                   for(j = ind[i-3]+3; j < i-3; j++)
                   {
                       outf[j] = 3;
                   }
                  // p = pp;
                  // pp = i -3;
                 // printf("CTRL+A\nCTRL+C\nCTRL+V\n");
               }
           }
           else if (arr[1] > arr[2])
           {
               index = i-4;
               sol[i] = arr[1];
              
               outf[pp+1] = 1;
               outf[pp+2] = 2;
              
              // for(j = 0; j < buf[1]; j++)
                //       outf[j] = 0;
               for(j = pp+3; j <=i; j++)
                   outf[j] = 3;
               ind[i] = pp;
               if(ind[pp] >= 3){
               outf[ind[pp]+1] = 1;
               outf[ind[pp]+2] = 2;
               }
               for(j = ind[pp]+3; j <= pp; j++)
               outf[j] = 3;
               
               //outf[i-1] = outf[i-2];
               //outf[i-2]= outf[i-3];
               //printf("CTRL+V\n");
           }
           else
           {
              
               index = i-3;
               sol[i] = arr[2];
               outf[i] = 3;
             
               outf[i-1] = 2;
               outf[i-2] = 1;
               
               ind[i] = i-3;
               outf[ind[i-3]+1] = 1;
               outf[ind[i-3]+2] = 2;
               for(j = ind[i-3]+3; j < i-3; j++)
               {
                   outf[j] = 3;
               }
               //p = pp;
              // pp = i -3;
              
               //printf("CTRL+A\nCTRL+C\nCTRL+V\n");
               
           }
          
          // sol[i] = max(arr[0] , arr[1], arr[2]);
        
           printf("\n%lld %lld %lld\n", arr[0], arr[1], arr[2]);
           printf("%lld %lld %lld\n", buf[0], buf[1], buf[2]);
           printf("p = %u pp = %u\n", p, pp);
           for(j = 1; j <= i; j++)
       {
           
       //    printf(out[outf[j]]);
       }
        p = pp;
           pp = i - 3;
       }
   }
   i = 1;
   while(i+1 < N && outf[i+1] != 2)
   {
       outf[i] = 0;
       i++;
   }
     printf("\n\nKey Sequences:\n\n");
   //  if(N <= 6)
     {
       //  printf("A\nA\nA\nA\nA\nA\n");
         
     }
     //else
     {
       for(i = 1; i <= N; i++)
       {
           
           printf(out[outf[i]]);
       }
     }
   
   for(i = 1; i <= N; i++)
       {
           
           printf("%u ",ind[i]);
       }
   printf("\nM = %llu\n", sol[N]);
   

}


</syntaxhighlight>




blog comments powered by Disqus