【CCF】——中间数(详细分析)

问题描述
  在一个整数序列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(∩_∩)O哈哈~。
一看到中间数,一般都和分奇偶有关,因为奇偶的中间数不一定一样,偶数比较麻烦,但是这道题显然是没有必要分奇偶的,先举个偶数的例子,样例中的2 6 5 6 3 5,按照从小到大排序后为2 3 5 5 6 6,下标为2和3的都是该组合的中间数,先看n/2=3,即为5,向左寻找,符合条件的为2 3,len1=2,向右寻找,符合条件的为6 6,len2=2,满足。若为n/2-1,即5,向左寻找,符合条件的为2 3,len1=2,向右寻找,符合条件的为6 6,len2=2,也符合,因为相同的都被过滤掉了,所以偶数直接n/2即可,这样还可以和奇数的中间数下标一致,减少了代码数量。再举个奇数的例子,样例中的3 4 6 6 7,按照从小到大排序后为3 4 6 6 7,中间数n/2=2,即a[2]=6,向左寻找,符合条件的为3 4,len1=2,向右寻找,符合条件的为7,len2=1,不满足,所以输出-1。总之向左和向右计数时,只有和mid值不相等的才计数
#include <iostream>
#include <algorithm>
using namespace std;

int main(){
    
    
	ios::sync_with_stdio(false);
	int n;
	cin >> n;
	int a[n];
	for(int i = 0;i<n;i++){
    
    
		cin >> a[i];
	}
	sort(a,a+n);
	int len1 = 0,len2 = 0;
	int mid_index = n/2,mid = a[n/2];
	//只有一个数的时候,左右相等,一定符合,直接输出,
	//这样可以防止后边循环中的下标越界错误,因为1/2=0,而0-1=-1,下标越界
	if(n==1){
    
    
		cout << a[0];
		return 0;
	}
	for(int i = mid_index-1;i>=0;i--){
    
    
		if(a[i]!=mid)
			len1++;
	}
	for(int i = mid_index+1;i<n;i++){
    
    
		if(a[i]!=mid)
			len2++;
	}
	if(len1==len2)
		cout << mid;
	else
		cout << -1;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45845039/article/details/108549464