# Counting the minimum number of blocks to remove to form a triangular temple

PROBLEM STATEMENT :

You want to build a temple for snakes. The temple will be built on a mountain range, which can be thought of as n blocks, where height of i-th block is given by hi. The temple will be made on a consecutive section of the blocks and its height should start from 1 and increase by exactly 1 each time till some height and then decrease by exactly 1 each time to height 1, i.e. a consecutive section of 1, 2, 3, .. x-1, x, x-1, x-2, .., 1 can correspond to a temple. Also, heights of all the blocks other than of the temple should have zero height, so that the temple is visible to people who view it from the left side or right side.

You want to construct a temple. For that, you can reduce the heights of some of the blocks. In a single operation, you can reduce the height of a block by 1 unit. Find out minimum number of operations required to build a temple.

INPUT

The first line of the input contains an integer T denoting the number of test cases. The description of T test cases follows.

The first line of each test case contains an integer n.

The next line contains n integers, where the i-th integer denotes hi

OUTPUT

For each test case, output a new line with an integer corresponding to the answer of that testcase.

CONSTRAINTS

1 ≤ T ≤ 10

2 ≤ N ≤ 105

1 ≤ Hi ≤ 10^9

Example Input

3
3
1 2 1
4
1 1 2 1
5
1 2 6 2 1


Output

0
1
3


MY SOLUTION

#include <stdio.h>

void quickSort(int arr[], int low, int high);
int partition (int arr[], int low, int high);
void swap(int* a, int* b);

int main(void) {
int t=0, i=0, n=0, move=0, j=0;
scanf("%d\n", &t);
for(i=1;i<=t;++i)
{
scanf("%d\n", &n);
int arr[n];
int i5;
for(i5=0;i5<n;++i5)
scanf("%d ", &arr[i5]);

quickSort(arr, 0, n-1);

int max= (arr[n-1]!=arr[n-2])?arr[n-2]+1:arr[n-1];
move = arr[n-1]-max;
--max;
int i3=0;
for(i3=n-2;i3>0;--max)
{
move+=((arr[i3]-max)+(arr[i3-1]-max));
i3-=2;
if(max==1)
{
break;
}
}
for(j=0;j<=i3;++j)
{
move+=arr[j];
}
printf("%d\n", move);
}
return 0;
}

// A utility function to swap two elements
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}

/* This function takes last element as pivot, places
the pivot element at its correct position in sorted
array, and places all smaller (smaller than pivot)
to left of pivot and all greater elements to right
of pivot */
int partition (int arr[], int low, int high)
{
int pivot = arr[high];    // pivot
int i = (low - 1);  // Index of smaller element
int j;

for (j = low; j <= high- 1; j++)
{
// If current element is smaller than or
// equal to pivot
if (arr[j] <= pivot)
{
i++;    // increment index of smaller element
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i + 1], &arr[high]);
return (i + 1);
}

/* The main function that implements QuickSort
arr[] --> Array to be sorted,
low  --> Starting index,
high  --> Ending index */
void quickSort(int arr[], int low, int high)
{
if (low < high)
{
/* pi is partitioning index, arr[p] is now
at right place */
int pi = partition(arr, low, high);

// Separately sort elements before
// partition and after partition
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}

• Welcome to Code Review. Is this a programming-challenge, and if so, can you cite the source? May 27, 2017 at 23:11
• Looks like codechef.com/SNCKPA17/problems/SNTEMPLE
– vnp
May 28, 2017 at 3:04
• I don't think the code is correct. For an input of 1 2 3 2 0 it returns -1.
– vnp
May 28, 2017 at 3:21
• @vnp.. i get it. thanks for pointing it out. May 28, 2017 at 5:42
• also, am i correct in assuming that my program runs for longer time coz i'm implementing sorting?? May 28, 2017 at 5:44

The code would be much more readable if there were spaces between the operators and the operands in the assignment statements and conditions, increment (++) and decrement (--) are the exceptions to this:

int main(void) {
int t = 0;
int n = 0;
int move = 0;

scanf("%d\n", &t);
for(int i = 1; i <= t; ++i)
{
scanf("%d\n", &n);
int arr[n];
for(int i5 = 0; i5 < n; ++i5)
{
scanf("%d ", &arr[i5]);
}

quickSort(arr, 0, n-1);

int max = (arr[n-1] != arr[n-2]) ? arr[n-2] +1 : arr[n-1];
move = arr[n-1] - max;
--max;

int i3;
for(i3 = n-2; i3 > 0; --max)
{
move += ((arr[i3] - max) + (arr[i3-1] - max));
i3 -= 2;
if(max == 1)
{
break;
}
}

for(int j = 0; j <= i3; ++j)
{
move += arr[j];
}
printf("%d\n", move);
}
return 0;
}


The i5 scanf() is not properly indented. Since the code brackets all for loops and if statements the i5 loop should also be bracketed as shown above.

Declare the Variables as Needed
The for loop control variables can be declared in the beginning of the for loop as shown for i, i5 and j.

The i3 variable is properly declared outside the for loop since it is used in statements following the for loop.

It's easier to read initiations when they are on separate lines as shown above.

Your code is not working for some cases. Consider for example input 1 1 2 2 4. The answer should be 6, but your code returns 1.

• I wouldn't say it's an answer and it's poorly written. May 28, 2017 at 11:27
• @t3chb0t This is a valid answer. As per the help center, discussing correctness in unanticipated cases is fair game. Furthermore, we have no obligation to provide a debugged version of the code. May 28, 2017 at 13:10

You can use mergesort instead of quicksort as that may encounter a Time Limit Exceeded.

• Mergesort and quicksort have the same time complexity. How can that encounter a time limit exceeded? May 28, 2017 at 8:13