CCF CSP 201612-1.中间数

问题描述

  在一个整数序列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。


方法一:暴力法

双重循环,时间复杂度为O(n^2)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <cstdio>

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

// 是否存在中间数
bool exists = false;
// left为小于某数的元素个数,right为大于某数的元素个数
int left, right;
left = right = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == j) {
continue;
}
if (arr[i] > arr[j]) {
left++;
}
if (arr[i] < arr[j]) {
right++;
}
}
if (left == right) {
exists = true;
printf("%d\n", arr[i]);
break;
}
// 重置为0
left = right = 0;
}
if (!exists) {
printf("-1\n");
}

return 0;
}

方法二:

先排序,然后找到中间位置mid。分别统计出左右两边与其不相等的元素个数left、right,若left等于right,则mid代表的元素为中间数;否则,不存在中间数。该方法的时间复杂度为O(n log n)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <cstdio>
#include <algorithm>
using namespace std;

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

sort(arr, arr + n);

int mid = n / 2;
// left为小于arr[mid]的元素个数,right为大于arr[mid]的元素个数
int left = mid, right = n - mid - 1;

for (int i = mid - 1; i >= 0; i--) {
if (arr[i] != arr[mid]) {
break;
}
left--;
}
for (int i = mid + 1; i < n; i++) {
if (arr[i] != arr[mid]) {
break;
}
right--;
}

if (left == right) {
printf("%d\n", arr[mid]);
} else {
printf("-1\n");
}

return 0;
}

----------本文结束感谢您的阅读----------
坚持原创技术分享,您的支持将鼓励我继续创作!