Problem:
Score : 400 points

Problem Statement

Takahashi has N sticks that are distinguishable from each other. The length of the i-th stick is L_i.

He is going to form a triangle using three of these sticks. Let a, b, and c be the lengths of the three sticks used. Here, all of the following conditions must be satisfied:

a < b + c

b < c + a

c < a + b

How many different triangles can be formed? Two triangles are considered different when there is a stick used in only one of them.

Constraints

All values in input are integers.

3 \leq N \leq 2 \times 10^3

1 \leq L_i \leq 10^3

Input

Input is given from Standard Input in the following format:

N
L_1 L_2 ... L_N

Constraints

Print the number of different triangles that can be formed.

Sample Input 1

4
3 4 2 1

Sample Output 1

1

Only one triangle can be formed: the triangle formed by the first, second, and third sticks.

Sample Input 2

3
1 1000 1

Sample Output 2

0

No triangles can be formed.

Sample Input 3

7
218 786 704 233 645 728 389

Sample Output 3

23

Solution in C (Clang 3.8.0) (judge verdict: Accepted)

#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include <math.h>


int merge(long int a1[], long int a2[], long int a1_size, long int a2_size, long int a[]);
int mergeSort(long int a[], long int number);

int main(void)
{
	long int n;
	long int count;
	long int i, j, k;
	long int work;
	long int flg;
	long int l[2000];
	
	scanf("%ld", &n);
	
	for(i = 0; i < n; i++) {
		scanf("%ld", &l[i]);
	}
	
	mergeSort(l, n);
	/*
	for(i = 0; i < n; i++) {
		printf("%ld\n", l[i]);
	}
	*/
	
	count = 0;
	
	for(i = 0; i < n - 2; i++) {
		flg = 0;
		for(j = i + 1; j < n - 1; j++) {
			if(i == j) {
				continue;
			}
			for(k = j + 1; k < n; k++) {
				if( (i == k) || (j == k) ) {
					continue;
				}
				if(l[i] < l[j] + l[k]) {
					count++;
				} else {
					if(k == j + 1) {
						flg = 1;
					}
					break;
				}
			}
			if(flg) {
				break;
			}
		}
	}
	
	printf("%ld\n", count);
	
	return 0;
}

int merge(long int a1[], long int a2[], long int a1_size, long int a2_size, long int a[])
{
	long int i = 0, j = 0;
	
	while( (i < a1_size ) || (j < a2_size) ){
		if( (j >= a2_size ) || ( (i < a1_size) && (a1[i] > a2[j]) ) ) {
			a[i + j] = a1[i];
			i++;
		} else {
			a[i + j] = a2[j];
			j++;
		}
	}
	
	return 0;
}


int mergeSort(long int a[], long int number)
{
	long int m = number / 2, n = number - m;
	long int a1[m];
	long int a2[n];
	int i, j;
	
	if(number > 1) {
		for(i = 0; i < m; i++) {
			a1[i] = a[i];
		}
		for(i = 0; i < n; i++) {
			a2[i] = a[m + i];
		}
		mergeSort(a1, m);
		mergeSort(a2, n);
		merge(a1, a2, m, n, a);
	}
	
	return 0;
}