here is my code and it always output -1 and I didn't know why. any help? Input The first line contains an integer t (1≤t≤104) — the number of test cases.
The first line of each test case contains an integer n (1≤n≤2⋅105) — the length of the array.
The second line of each test case contains n integers a1,a2,…,an (1≤ai≤n) — the elements of the array.
It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.
Output For each test case, print any value that appears at least three times or print -1 if there is no such value.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, size,*arr, *frr,count,*ptr,g,s;
scanf("%d", &n);
ptr = (int*)malloc(n * sizeof(int));
for (int i = 0;i < n; i )
{
scanf("%d",&size);
arr = (int*)malloc(size * sizeof(int));
frr = (int*)malloc(size * sizeof(int));
for(int j = 0; j < size; j )
{
scanf("%d",arr j);
*(frr j) = -1;
}
if(size >= 3)
{
for (g = 0; g < size ; g )
{
count=1;
for(s = g 1; s < size;s )
{
if(*(arr g) == *(arr s))
{
count ;
*(frr s) = 0;
}
}
if(*(frr g) != 0 )
{
*(frr g) = count;
}
if(*(frr g) >= 3)
{
*(ptr i) = *(arr g);
}else
{
*(ptr i) = -1;
}
}
}else
{
*(ptr i) = -1;
}
free(arr);
free(frr);
}
for(int j = 0;j<n;j )
{
printf("%d\n",*(ptr j));
}
}
CodePudding user response:
The problem is that you set *(ptr i)
to -1
for each element of the array. This means that a later element of the array that is not repeated three times will reset *(ptr i)
to -1
.
Change this
if(*(frr g) >= 3)
{
*(ptr i) = *(arr g);
}
else
{
*(ptr i) = -1;
}
to this
if(*(ptr i) == -1 && *(frr g) >= 3)
{
*(ptr i) = *(arr g);
}
and at the beginning add this
ptr = (int*)malloc(n * sizeof(int));
for (int i = 0;i < n; i )
{
*(ptr i) = -1;
But as has already been said in the comments you do not need either the ptr
array or the frr
array. You only run one test at a time so there is no need to keep all the test results before you print any of them out. And you only need to save the frequency of the current element you are testing, so you don't need an array for that either.
And make your code readable, change *(arr g)
to arr[g]
. They both work exactly the same.
CodePudding user response:
For starters this array allocation
ptr = (int*)malloc(n * sizeof(int));
does not make a sense. For each given sequence of numbers you can at once output whether the sequence contains three equal elements or not without storing this information in the allocated array.
Also allocating this auxiliary array
frr = (int*)malloc(size * sizeof(int));
makes the code unsafe and inefficient.
It does not make a sense to travers the array if an element that occurs already three times is found.
Otherwise this code snippet
if(*(frr g) >= 3)
{
*(ptr i) = *(arr g);
}else
{
*(ptr i) = -1;
}
for elements that are present in the tail of the array arr
can incorrectly
set the value ptr[i]
to -1
though early there was already found a preceding element that occurs three times.
Without the redundant arrays pointed to by the pointers ptr
and frr
the program can look the following way
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
size_t t = 0;
scanf( "%zu", &t );
while (t--)
{
size_t n = 0;
scanf( "%zu", &n );
int result = -1;
if (n)
{
int *a = malloc( n * sizeof( int ) );
for (size_t i = 0; i < n; i )
{
scanf( "%d", a i );
}
for (size_t i = 2; result == -1 && i < n; i )
{
int count = 1;
for (size_t j = i; count != 3 && j-- != 0; )
{
if (a[j] == a[i]) count;
}
if (count == 3) result = a[i];
}
free( a );
}
printf( "%d\n", result );
}
}
CodePudding user response:
I would approach the problem altogether differently. Since the range of the elements is not explicitly bounded, it is a bit tricksome to manage a frequency table. But the maximum number of elements in each test array is pretty small, so it is feasible to
- declare an array large enough to hold all the elements of any test case
- for each test case,
- read all the elements into the (one) array
- sort the array (
qsort()
, or roll your own insertion or selection sort) - scan the sorted array to easily detect and report values that appear at least thrice