Arjun Suresh (talk | contribs) |
Arjun Suresh (talk | contribs) |
||
| (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> | ||
| − | + | ||
| + | //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; | |
| − | + | 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"> | |
| − | + | #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"); | |
| − | + | } | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
} | } | ||
| Line 226: | Line 185: | ||
{{Template:FBD}} | {{Template:FBD}} | ||
| + | |||
| + | [[Category:Placement Coding Questions from Arrays]] | ||
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).
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">
//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>
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">
//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>
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).
<syntaxhighlight lang="c" name="printa">
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>