I'm trying to solve a problem where I have to identify the number of pairs in an array that have the same mean/average as the original array.
Though I have solved the problem with nested loops(refer to the code below), I wanted to reduce the complexity of my solution, and I'm not getting any ideas so far.
Update: 'T' is just a variable representing the number of test cases. You can assume that to be 1.
#include <stdio.h>
#include <stdlib.h>
int comparator(const void *p, const void *q) {
int l = *(int *)p;
int r = *(int *)q;
return (l-r);
}
int fSum(int *Arr, int N){
int sum = 0;
for(int i=0; i<N; i ){
sum =Arr[i];
}
return sum;
}
int main(void) {
int i=1, T, N, pos = 1, j=0, k=0, c = 0, sum;
int Arr[100000];
scanf("%d",&T);
while(i<=T){
scanf("%d", &N);
c = 0;
j = 0;
while(j<N){
scanf("%d", &Arr[j]);
j;
}
qsort(Arr, N, sizeof(int), comparator);
sum = fSum(Arr, N);
for(j=0; j<N-1; j ){
for(k=N-1; k>=j 1; k--){
if(sum*2 == ((Arr[j] Arr[k])*N)) {
c ;
}
else{
if(sum*2 > ((Arr[j] Arr[k])*N))
break;
}
}
}
printf("%d\n", c);
i;
}
return 0;
}
CodePudding user response:
The general approach to problems like this is a single loop that maintains two indexes. One index starts at the beginning of the array, the other at the end. When the indexes meet in the middle, the loop is finished. In the body of the loop, the code must decide whether to update one index, or the other, or both.
For this particular problem, there are couple of additional wrinkles, which are caused by duplicates in the array.
For example, given the array { 1, 1, 1, 4, 5, 12, 15, 15, 18 }
, there are 7 pairs. There are three 1's that can be matched with either of the two 15's, giving 6 possible pairs. The 4,12
pair is the seventh pair. So when the code finds a pair of distinct number that have the correct average, it must count the number of duplicates of each number. The number of pairs is then updated by the product of the two counts.
Given the array { 2, 3, 4, 8, 8, 8, 12, 12, 15 }
, there are 5 pairs. Three pairs due to the three 8's, plus two ways to pair a 4 with a 12. When the average value is present in the array, and is duplicated, one index will reach the first instance of the average while the other will reach the last. The duplicate count can be computed from the two indexes, and the number of pairs is the number of ways to choose any two of the duplicates.
Here's a sample implementation using a single loop that updates two indexes:
#include <stdio.h>
void showArray(int Arr[], int N)
{
printf("Arr[] = {");
if (N > 0)
printf(" %d", Arr[0]);
for (int i = 1; i < N; i )
printf(", %d", Arr[i]);
printf(" }\n");
}
int computeSum(int Arr[], int N)
{
int sum = 0;
for (int i=0; i < N; i )
sum = Arr[i];
return sum;
}
int solve(int Arr[], int N)
{
showArray(Arr, N);
int sum = computeSum(Arr, N);
printf("N=%d sum=%d\n", N, sum);
int pairs = 0;
for (int j=0, k=N-1; k > j; )
{
if ((Arr[j] Arr[k])*N > sum*2)
{
// the average is too high, so skip the larger value
k--;
}
else if ((Arr[j] Arr[k])*N < sum*2)
{
// the average is too low, so skip the smaller value
j ;
}
else if (Arr[j] == Arr[k])
{
// handle the case where the average value is present and duplicated
int repeat = k - j 1;
pairs = (repeat * (repeat-1)) / 2;
break;
}
else
{
// handle the case where two distinct numbers in the array have the correct average
// note that if there are duplicates of the numbers, the indexes are updated to the next non-duplicate
int oldj = j ;
while (Arr[j] == Arr[oldj])
j ;
int oldk = k--;
while (Arr[k] == Arr[oldk])
k--;
pairs = (j - oldj) * (oldk - k);
}
}
return pairs;
}
#define len(arr) (sizeof(arr) / sizeof(arr[0]))
int main(void)
{
int Arr1[] = { 1, 4, 5, 6, 6, 7, 7, 11, 15, 18 };
printf("pairs=%d\n\n", solve(Arr1, len(Arr1)));
int Arr2[] = { 1, 1, 1, 4, 5, 12, 15, 15, 18 };
printf("pairs=%d\n\n", solve(Arr2, len(Arr2)));
int Arr3[] = { 2, 3, 4, 8, 8, 8, 12, 12, 15 };
printf("pairs=%d\n\n", solve(Arr3, len(Arr3)));
}
Output from the code:
Arr[] = { 1, 4, 5, 6, 6, 7, 7, 11, 15, 18 }
N=10 sum=80
pairs=2
Arr[] = { 1, 1, 1, 4, 5, 12, 15, 15, 18 }
N=9 sum=72
pairs=7
Arr[] = { 2, 3, 4, 8, 8, 8, 12, 12, 15 }
N=9 sum=72
pairs=5