k largest elements exercise from geeksforgeeks - c

I am working on an exercise "k largest elements" from geeksforgeeks.org
https://practice.geeksforgeeks.org/problems/k-largest-elements/0
The task:
Given an array of N positive integers, print k largest elements from the array. The output elements should be printed in decreasing order.
Input:
The first line of input contains an integer T denoting the number of test cases. The first line of each test case is N and k, N is the size of array and K is the largest elements to be returned. The second line of each test case contains N input C[i].
Output:
Print the k largest element in descending order.
Constraints:
1 ≤ T ≤ 100
1 ≤ N ≤ 100 (actually 1000 as someone identified)
K ≤ N
1 ≤ C[i] ≤ 1000*
Example:
Input:
2
5 2
12 5 787 1 23
7 3
1 23 12 9 30 2 50
Output:
787 23
50 30 23
Explanation:
Testcase 1: 1st largest element in the array is 787 and second largest is 23.
Testcase 2: 3 Largest element in the array are 50, 30 and 23.
I have constructed a solution, which works with the initial test case, but later throws a segmentation fault. I cannot understand where could I get the segmentation fault:
Runtime Error:
Segmentation Fault (SIGSEGV)
Runtime Error
The problem with these exercises is that I do not know the input data to the test case, which generates the error. Bellow you will find my code, which is rather simple. Perhaps you can help me to identify what could cause the segmentation fault.
#include <stdio.h>
static int Arr[1024], Res[1024];
int main()
{
int t=0;
scanf("%d", &t);
while(t--)
{
int n=0,k=0, i=0,j=0,z=0;
scanf("%d %d", &n, &k);
// if(n>1000)
// printf("Gotya");
for(i=0; i<n; i++)
{
scanf("%d", &Arr[i]);
}
i=0;
int max_l = 0, max_h = 1000, j_max = 0;
for(i=0; i<k; i++)
{
for(j=0; j<n; j++)
{
if(Arr[j] >= max_l)
{
max_l = Arr[j];
j_max = j;
}
}
Res[i]= max_l;
max_l = 0;
Arr[j_max] = 0;
j_max = 0;
}
for(z=0; z<k; z++)
{
printf("%d ", Res[z]);
}
printf("\n");
}
return 0;
}

This site does not seem to be abiding by their constraints.
I made a login and modified the code to print if N>1000. The value of N is 20567
Wrong Answer. !!!Wrong Answer
Possibly your code doesn't work correctly for multiple test-cases (TCs).
The first test case where your code failed:
Input:
20567 18428
9737 16220 4527 21952 22174 12861 29801 8125 13670 9713 5742 14988 31137 21891 25646 18474 18286 30312 6105 19031 18587 15877 14546 29756 18364 24690 12129 16209 378 27774 16552 18302 8238 10483 1752 12929 5551 22299 14756 9871 18279 32386 23286 5182 16557 9726 7137 22434 24399 7661 3544 29878 11885 16318 29725 29438 25486 18099 18811 7275 12781 9700 20024 9087 26644 32648 12870 29873 2988 8560 12217 14099 26516 10964 10622 16434 16432 16210 8777 32574 8708 27444 8143 9067 32385 7410 20022 406 2846 22519 30665 32044 5803 1192 9457 30792 18658 419 30816 3867 64 23108 7056 8849 16915 18030 20332 30257 28883 22408 30029 25926 15541 30405 9255 29500 638 6313 7685 15180 3221 18889 14770 860 27229 30930 5305 30240 20929 8652 8592 18566 16145 16032 26129 20049 18188 8408 32297 16899 20286 6311 14036 17409 8332 3369 21833 21746 2061 27115 24177 20328 31259 1454 29342 9410 27562 26216 4474 24913 21977 1676 23102 15289 6087 32651 7204 13210 10920 15771 19230 880 23576 8375 11464 2706.................
Its Correct output is:
32768 32768 32766 32765 32761 32759 32757 32756 32756 32755 32754 32752 32747 32747 32747 32746 32743 32742 32741 32740 32739 32738 32738 32735 32735 32735 32733 32733 32732 32731 32730 32728 32728 32726 32726 32726 32725 32724 32719 32718 32718 32716 32714 32714 32708 32706 32706 32698 32694 32694 32691 32690 32690 32689 32688 32687 32684 32682 32676 32675 32672 32670 32663 32660 32658 32657 32657 32656 32651 32648 32646 32645 32644 32643 32638 32637 32637 32637 32637 32635 32632 32630 32630 32625 32625 32625 32623 32622 32622 32620 32619 32618 32616 32614 32614 32613 32613 32612 32608 32606 32606 32605 32598 32596 32593 32591 32589 32588 32586 32586 32586 32582 32582 32581 32580 32580 32579 32578 32574 32573 32571 32571 32567 32567 32566 32564 32564 32563 32562 32560 32560 32559 32559 32558 32555 32554 32552 32551 32551 32551 32550 32549 32549 32547 32547 32546 32544 32544 32543 32543 32540 32539 32538 32538 32537 32535 32533 32533 32533 32532 32531 32528 32527 32527 32526 32525 3252.................
And Your Code's output is:
Gotya
However, with the correct length of the array Arr and Res, you get an error of
Expected Time Limit < 1.996sec
Hint : Please optimize your code and submit again.
I leave this up to you.
Hint - Use qsort for a better sorting performance.

A set of points over a straight line is defined as correlative to some K if the absolute difference between any two points is a multiple of K. Given N (2 <= N <= 100000) points and some integer K (1 <= K <= 1000). Your task is to find the largest set which is correlative to K. You can assume that only one largest set exists. N and K will be in the first line of the input. N lines will follow, each one with a single integer, representing the location of one of the points. Print the size of the largest set of points which is correlative to K, in the first line of the input. Remaining lines will contain the points of the set, one per line, in increasing order.
Case 1:
For the input provided as follows:
5 2
1
2
3
4
5
Output of the program will be:
3
1
3
5
Case 2:
For the input provided as follows:
6 4
10
15
12
16
20
32
Output of the program will be:
4
12
16
20
32
#include <bits/stdc++.h>
using namespace std;
// function to find remainder set
int findSet(int arr[], int n, int k, int m) {
vector remainder_set[k];
// calculate remainder set array
// and push element as per their remainder
for (int i = 0; i < n; i++) {
int rem = arr[i] % k;
remainder_set[rem].push_back(arr[i]);
}
// check whether sizeof any remainder set
// is equal or greater than m
for (int i = 0; i < k; i++) {
if (remainder_set[i].size() >= m) {
cout <<m<< "\n";
for (int j = 0; j < m; j++){
cout << remainder_set[i][j] << "\n";
}
return 1;
}
}
return 0;
}
// driver program
int main() {
int n,k;
cin>>n>>k;
int arr[n];
for(int i=0;i<n;i++)
cin>>arr[i];
int z;
int m = sizeof(arr)/sizeof(int);
for(int i=m;i>0;i--)
{
z=findSet(arr, n, k, i);
if(z==1)
break;
}
}

Related

Splitting a 2D array size to a smaller 2D Array size in C

Disclaimer: I'm not very good with words, I have included a sample of how will it look like below.
So I'm trying to reduce this 4x4 array into a bunch of 2x2 arrays. (See sample below)
int disp[4][4] = {{12,4,32,9}, {19,24,3,4},{1,26,3,8},{3,24,7,5} };
/*
12 4 32 9 12 4 | 32 9
19 24 3 4 into something like 19 24 | 3 4
1 26 3 8 =============
3 24 7 5 1 26 | 3 8
3 24 | 7 5
*/
Take note: it is splitting it into smaller sizes (bunch of 2D arrays)
I have tried splitting it using a for loop code but only getting the 2nd quadrant.
code below:
int i,j;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
printf("%d\n",disp[i][j]);
see that this only gives me 12,4,19 and 24.
Is there a way to get the other quadrants? How would this work for bigger sizes? (Lets say 28x28 to 14x14) I would really appreciate the help. Thank you.
Let's consider a NXN matrix where N and quadrant_size be the required size of sub_matrix to be printed.
We first traverse to find the starting element to be printed in each sub_matrix.
i.e: From 0 to N incrementing by quadrant_size for row and 0 to N incrementing by quadrant_size for column.(First two loops in the below given code)
Let's say (x,y) index at any position. Now we print the matrix elements from (x,y) to (x+2,y+2)
The below code is generalized for any size of matrix NxN of required quadrant_size where N should be divisible by quadrant_size.
int quadrant_size=2;
//outer loop to traverse the starting elements of the sub array
for(int x=0 ; x<N ; x+=quadrant_size){
for(int y=0 ; y<N ; y+=quadrant_size){
//inner loop to print matrix
for(int i=x ; i<x+quadrant_size ; i++){
for(int j=y ; j<y+quadrant_size ; j++){
printf("%d ",disp[i][j]);
}
printf("\n");
}
printf("\n");
}
}
You need to add an offset to i and j depending on which quadrant you want to print.
For your specific case it could be:
int main() {
int disp[4][4] = {{12,4,32,9},
{19,24,3,4},
{1,26,3,8},
{3,24,7,5} };
// calculate quadrant size (it will be 2 in this case)
int qsize = sizeof disp[0] /sizeof disp[0][0] / 2;
int q = 3; // <--- The quadrant to print
int offset_i = 0; // Extra offsets for
int offset_j = 0; // the loop that prints
if (q == 1)
{
offset_j = qsize;
}
else if (q == 3)
{
offset_i = qsize;
}
else if (q == 4)
{
offset_i = qsize;
offset_j = qsize;
}
for(int i=0; i<qsize; i++)
{
for(int j=0; j<qsize; j++)
{
printf("%d ",disp[i + offset_i][j + offset_j]);
// Notice: ^^^^^^^^^^ ^^^^^^^^^^
}
printf("\n");
}
return 0;
}

pascal triangle in c without array [duplicate]

This question already has answers here:
Pascal's Triangle in C
(4 answers)
Closed 1 year ago.
I tried to code a program that will give the pascal triangle without using arrays and keeping in mind the formula that each element of the pascal triangle can be calculated as n choose k" and written like this:
n choose k = n! / k!(n-k)!
(for both n and k starting from 0)
so I also had to define the factorial function and it worked for the first 14 lines.
but in line 15 and more my numbers started to decrease and became also negative but I don't understand why this happened.
Here is the code:
#include <stdio.h>
int factorial(int a);
int main()
{
int row, j, i, space, tot;
scanf("%d", &row);
space=row;
for(i=0; i<row; i++)
{
for(space=0; space<row-i; space++)
{ printf(" "); }
for (j = 0; j <= i; j++)
{
if (j == 0 || i == 0)
{ tot=1; }
else
{
int n=factorial(i);
int k=factorial(j);
int z=factorial(i-j);
tot= n/(k*z);
}
printf("%6d", tot);
}
printf("\n");
}
}
int factorial(int a)
{
int fact=1;
for (int m=1; m<=a; m++)
{ fact*=m; }
return fact;
}
this is my output in line 15:
1 0 1 5 14 29 44 50 44 29 14 5 1 0 1
but the actual output should be this:
1 14 91 364 1001 2002 3003 3432 3003 2002 1001 364 91 14 1
I couldn't find the problem so I would be happy and thankful if anyone could help me.
If you don't care much about computation time then you could compute coefficient directly from their recursive definition.
int pascal(int x,int y) {
if (x==0 || y==0) return 1;
return pascal(x-1,y)+pascal(x,y-1);}

hackerrank solution in c for "Array Manipulation"

long arrayManipulation(int n, int queries_rows, int queries_columns, int** queries)
{
long num, a, b, maxnum = INT_MIN;
long* arrptr = calloc(n, sizeof(long));
for(int i = 0;i<(queries_rows);i++)
{
num = queries[i][2];
if(num==0)
{
continue;
}
printf("%ld ", num);
a = queries[i][0];
b = queries[i][1];
for(long i = a-1;i<b;i++)
{
arrptr[i] += num;
if(maxnum<(arrptr[i]))
{
maxnum = arrptr[i];
}
}
}
free(arrptr);
return maxnum;
}
I have to optimize this program so that it can be executed in less time can you help??
this program is supposed to initialize an array of a size n(function argument) with 0(lets call array arr)
then there will be query in form
a b k
1 2 3
4 5 6
and then in array arr we have add k between the limits a and b
and then return max of arr
example
Sample Input
5 3
1 2 100
2 5 100
3 4 100
Sample Output
200
Explanation
After the first update list will be 100 100 0 0 0.
After the second update list will be 100 200 100 100 100.
After the third update list will be 100 200 200 200 100.
The returned answer will be 200.
Actually you can think of a much better algorithm that will do the job in O(n) instead of doing the same thing in O(n*n) what you are doing.
So the algorithm looks like this
1-initialize the array with size n+1 with all the 0's in it
2-for every query L, R, X increase array[L] by the value of X and decrease the value of array[R+1] by X
3-last step would be to get the prefix sum of the array which will give you the final processed array where you can find the maximum and return as an answer.
For eg.
5 3
arr=[0,0,0,0,0,0]
step 1:
1 2 100
arr=[100 0 -100 0 0 0]
step 2:
2 5 100
arr=[100 100 -100 0 0 -100]
step 3:
3 4 100
arr=[100 100 0 0 -100 -100]
step 4:
prefix sum
arr=[100 200 200 200 100 0] -> That's your final array and then you can easily return maximum from this array
Hope this helps! tell me if you can't understand anything I will be happy to help
Since I have been working on it I found a good and understandable code on it with O(n) approach, it works well under required time and it doesn't have errors.
long arrayManipulation(int n, int queries_rows, int queries_columns, int** queries)
{
long num, a, b, maxnum = INT_MIN;
int* arrptr = calloc(n, sizeof(long));
for(int i=0;i<queries_rows;i++)
{
arrptr[queries[i][0] -1] +=queries[i][2];
arrptr[queries[i][1]] -= queries[i][2];
}
long count = 0;
for(int i=0;i<n;i++)
{
count += arrptr[i];
arrptr[i]=count;
if(count>maxnum) maxnum=count;
}
printf("%ld\n",maxnum);
free(arrptr);
return maxnum;
}

how to print a table of even squares?

This program prompts the user a number and then outputs a table of even squares ranging from 2 to the number.
#include <stdio.h>
int main(void)
{
int i, n;
puts(This program prints a table of even squares.);
printf("Enter range of the squares square: ");
scanf("%d", &n);
for (i = 2; i * i <= n; i += 2)
printf("%d\n", i * i);
return 0;
}
for example:
Enter range of the squares: 123
2 4
4 16
6 36
8 64
10 100
The problem is did not print 121 (which is 11 * 11). I am new to C and not really good in using loops. Please help!
for (i = 2; i * i <= n; i += 2)
You're starting at 2 and incrementing by 2. i will never be 11.

Segmentation fault due to recursion

I'm writing a program that is to take a number between 1-10 and display all possible ways of arranging the numbers.
Ex
input: 3
output:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Whenever I input 9 or 10, the program gives a segmentation fault and dumps the core. I believe the issue is my recursive algorithm is being called too many times. Could someone help point out how I could limit the amount of recursive calls necessary? Here is my current code:
void rearange(int numbers[11], int index, int num, int fact) {
int temp = numbers[index];
numbers[index] = numbers[index-1];
numbers[index-1] = temp;
int i;
for (i = 1; i <= num; ++i) // print the current sequence
{
printf("%d ", numbers[i]);
}
printf("\n");
fact--; // decrement how many sequences remain
index--; // decrement our index in the array
if (index == 1) // if we're at the beginning of the array
index = num; // reset index to end of the array
if (fact > 0) // If we have more sequences remaining
rearange(numbers, index, num, fact); // Do it all again! :D
}
int main() {
int num, i; // our number and a counter
printf("Enter a number less than 10: ");
scanf("%d", &num); // get the number from the user
int numbers[11]; // create an array of appropriate size
// fill array
for (i = 1; i <= num; i++) { // fill the array from 1 to num
numbers[i] = i;
}
int fact = 1; // calculate the factorial to determine
for (i = 1; i <= num; ++i) // how many possible sequences
{
fact = fact * i;
}
rearange(numbers, num, num, fact); // begin rearranging by recursion
return 0;
}
9! (362880) and 10! (3628800) are huge numbers that overflow the call stack when you do as many recursive calls. Because all the local variables and formal parameters have to be stored. You either you have to increase the stack size or convert the recursion into iteration.
On linux, you can do:
ulimit -s unlimited
to set the stack size to unlimited. The default is usually 8MB.
Calculating permutations can be done iteratively, but even if you do it recursively there is no need to have a gigantic stack (like answers suggesting to increase your system stack say). In fact you only need a tiny amount of your stack. Consider this:
0 1 <- this needs **2** stackframes
1 0 and an for-loop of size 2 in each stackframe
0 1 2 <- this needs **3** stackframes
0 2 1 and an for-loop of size 3 in each stackframe
1 0 2
1 2 0
2 1 0
2 0 1
Permuting 9 elements takes 9 stackframes and a for-loop through 9 elements in each stackframe.
EDIT: I have taken the liberty to add a recursion-counter to your rearrange-function, it now prints like this:
Enter a number less than 10: 4
depth 1 1 2 4 3
depth 2 1 4 2 3
depth 3 4 1 2 3
depth 4 4 1 3 2
depth 5 4 3 1 2
depth 6 3 4 1 2
depth 7 3 4 2 1
depth 8 3 2 4 1
depth 9 2 3 4 1
depth 10 2 3 1 4
depth 11 2 1 3 4
depth 12 1 2 3 4
depth 13 1 2 4 3
depth 14 1 4 2 3
depth 15 4 1 2 3
depth 16 4 1 3 2 which is obviously wrong even if you do it recursively.
depth 17 4 3 1 2
depth 18 3 4 1 2
depth 19 3 4 2 1
depth 20 3 2 4 1
depth 21 2 3 4 1
depth 22 2 3 1 4
depth 23 2 1 3 4
depth 24 1 2 3 4
....
The recursion-leafs should be the only ones which output so the depth should be constant and small (equal to the number you enter).
EDIT 2:
Ok, wrote the code. Try it out:
#include "stdio.h"
void betterRecursion(int depth, int elems, int* temp) {
if(depth==elems) {
int j=0;for(;j<elems;++j){
printf("%i ", temp[j]);
}
printf(" (at recursion depth %u)\n", depth);
} else {
int i=0;for(;i<elems;++i){
temp[depth] = i;
betterRecursion(depth+1, elems, temp);
}
}
}
int main() {
int temp[100];
betterRecursion(0, 11, temp); // arrange the 11 elements 0...10
return 0;
}
I'd make your rearange function iterative - do while added, and recursive call removed:
void rearange(int numbers[11], int index, int num, int fact) {
int temp;
do
{
temp = numbers[index];
numbers[index] = numbers[index-1];
numbers[index-1] = temp;
int i;
for (i = 1; i <= num; ++i) // print the current sequence
{
printf("%d ", numbers[i]);
}
printf("\n");
fact--; // decrement how many sequences remain
index--; // decrement our index in the array
if (index == 1) // if we're at the beginning of the array
index = num; // reset index to end of the array
} while (fact > 0);
}
This is not a task for a deep recursion.
Try to invent some more stack-friendly algorithm.
Following code has rather troubles with speed than with stack size...
It's a bit slow e.g. for n=1000 but it works.
#include <stdio.h>
void print_arrangement(int n, int* x)
{
int i;
for(i = 0; i < n; i++)
{
printf("%s%d", i ? " " : "", x[i]);
}
printf("\n");
}
void generate_arrangements(int n, int k, int* x)
{
int i;
int j;
int found;
if (n == k)
{
print_arrangement(n, x);
}
else
{
for(i = 1; i <= n; i++)
{
found = 0;
for(j = 0; j < k; j++)
{
if (x[j] == i)
{
found = 1;
}
}
if (!found)
{
x[k] = i;
generate_arrangements(n, k + 1, x);
}
}
}
}
int main(int argc, char **argv)
{
int x[50];
generate_arrangements(50, 0, x);
}
Your program is using too many recursions unnecessarily. It is using n! recursions when actually n would be enough.
To use only n recursions, consider this logic for the recursive function:
It receives an array nums[] of n unique numbers to arrange
The arrangements can have n different first number in them, as there are n different numbers in the array
(key step) Loop over the elements of nums[], and in each iteration create a new array but with the current element removed, and recurse into the same function passing this shorter array as parameter
As you recurse deeper, the parameter array will be smaller and smaller
When there is only one element left, that's the end of the recursion
Using this algorithm, your recursion will not be deeper than n and you will not get segmentation fault. The key is in the key step, where you build a new array of numbers that is always 1 item shorter than the input array.
As a side note, make sure to check the output of your program before you submit, for example run it through | sort | uniq | wc -l to make sure you are getting the correct number of combinations, and check that there are no duplicates with | sort | uniq -d (the output should be empty if no dups).
Spoiler alert: here's my implementation in C++ using a variation of the above algorithm:
https://gist.github.com/janosgyerik/5063197

Resources