问题描述
在一个整数序列a1, a2, …, an中,如果存在某个数,大于它的整数数量等于小于它的整数数量,则称其为中间数。在一个序列中,可能存在多个下标不相同的中间数,这些中间数的值是相同的。
给定一个整数序列,请找出这个整数序列的中间数的值。
输入格式
输入的第一行包含了一个整数n,表示整数序列中数的个数。
第二行包含n个正整数,依次表示a1, a2, …, an。
输出格式
如果约定序列的中间数存在,则输出中间数的值,否则输出-1表示不存在中间数。
样例输入
6
2 6 5 6 3 5
样例输出
5
样例说明
比5小的数有2个,比5大的数也有2个。
样例输入
4
3 4 6 7
样例输出
-1
样例说明
在序列中的4个数都不满足中间数的定义。
样例输入
5
3 4 6 6 7
样例输出
-1
样例说明
在序列中的5个数都不满足中间数的定义。
评测用例规模与约定
对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ ai ≤ 1000。
实现
二路归并排序
#include <cstdio>
int l[1024], r[1024];
void merge_sort(int a[], int n)
{
const int INF = 2147483647;
if (n == 2)
{
if (a[0] > a[1])
{
int tmp = a[0];
a[0] = a[1];
a[1] = tmp;
}
return ;
}
if (n < 2)
{
return ;
}
int mid = n / 2;
merge_sort(a, mid);
merge_sort(a + mid, n - mid);
int lenl = mid;
int lenr = n - mid;
for (int i = 0; i < lenl; i++)
{
l[i] = a[i];
}
l[lenl] = INF;
for (int i = 0; i < lenr; i++)
{
r[i] = a[mid + i];
}
r[lenr] = INF;
int pl = 0, pr = 0;
for (int i = 0; i < n; i++)
{
if (r[pr] >= l[pl])
{
a[i] = l[pl];
pl++;
continue;
}
a[i] = r[pr];
pr++;
}
}
int main(void)
{
int n;
int ans;
int arr[1024];
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
merge_sort(arr, n);
/*
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
*/
int mid = n / 2;
if (0 == n % 2)
{
if (arr[mid] != arr[mid - 1])
{
printf("-1\n");
return 0;
}
int sumL = 0, sumR = 0;
for (int i = 0; i < mid; i++)
{
if (arr[i] < arr[mid])
{
sumL++;
}
}
for (int i = mid + 1; i < n; i++)
{
if (arr[i] > arr[mid])
{
sumR++;
}
}
if (sumL != sumR)
{
printf("-1\n");
return 0;
}
printf("%d\n", arr[mid]);
return 0;
}
int sumL = 0, sumR = 0;
mid = (n / 2);
for (int i = 0; i < mid; i++)
{
if (arr[i] < arr[mid])
{
sumL++;
}
}
for (int i = mid + 1; i < n; i++)
{
if (arr[i] > arr[mid])
{
sumR++;
}
}
if (sumL != sumR)
{
printf("-1\n");
return 0;
}
printf("%d\n", arr[mid]);
return 0;
}