CCF201612-1 Intermediate Number (Solution 2) (100 points) (Repeal!!!)

Question number: 201612-1
Question name: middle number
time limit: 1.0s
Memory limit: 256.0MB
Problem Description:
Problem Description
  In a sequence of integers a 1 , a 2 , …, an n , if there is a number, the number of integers greater than it is equal to the number of integers less than it, it is called an intermediate number. In a sequence, there may be multiple intermediate numbers with different subscripts, and the values ​​of these intermediate numbers are the same.
  Given a sequence of integers, find the value of the middle number of this sequence of integers.
input format
  The first line of input contains an integer n, the number of numbers in the sequence of integers.
  The second line contains n positive integers representing a 1 , a 2 , …, a n in order .
output format
  If the middle number of the agreed sequence exists, output the value of the middle number, otherwise output -1 to indicate that there is no middle number.
sample input
6
2 6 5 6 3 5
Sample output
5
Sample description
  There are 2 numbers smaller than 5 and 2 numbers larger than 5.
sample input
4
3 4 6 7
Sample output
-1
Sample description
  在序列中的4个数都不满足中间数的定义。
样例输入
5
3 4 6 6 7
样例输出
-1
样例说明
  在序列中的5个数都不满足中间数的定义。
评测用例规模与约定
  对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ a i ≤ 1000。

问题链接:CCF201612试题

问题描述:首先输入正整数n,接着输入n个正整数,如果存在一个数,比该数大或比该数小的数则输出该数,如果不存在则输出-1。

问题分析:这个问题可以用排序来解决,这是基础。可以证明,如果存在答案则必定所有数排序后的中间位置。

排序方法上有以下几种:

1.对n个数进行排序,找出中间那个数,然后将中间那个数的左右与其相等的数去掉,看左右剩下的数个数是否相等,如果相等则中间那个数就是答案,否在输出-1。

2.使用分治法,按照快速排序的基本思想来处理,只需要将中间的那个数找到即可。

3.使用STL的map类对数据进行排序。这种方法在同值的数据比较多时候,存储上会节省一些。

4.按照桶排序的基本思想,将相同的值放入同一个桶中,即对同值数据进行计数,然后再计算中间值。

程序说明:本程序采用上述的第1种方法实现。STL的algorithm中封装了许多算法,排序函数sort()其中之一,使用起来非常简单。

使用函数lower_bound()和upper_bound()来实现的话,代码会更加简单,后文也给出了这种版本的代码。数据必须在排序之后才能使用这两个函数。


参见:

CCF201612-1 中间数(100分)

CCF201612-1 中间数(解法三)(100分)


提交后得100分的C++语言程序如下:

/* CCF201612-1 中间数 */

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1000;
int val[N];

int main()
{
    int n, mid, leftcount, rightcount;

    // 输入数据
    cin >> n;
    for(int i=0; i<n; i++)
        cin >> val[i];

    // 排序
    sort(val, val+n);

    // 找出中间数
    mid = n / 2;
    leftcount = mid;
    rightcount = n - mid - 1;
    // 去掉左边与中间相同值数的个数
    for(int i=mid-1; i>=0; i--)
        if(val[i] == val[mid])
            leftcount--;
        else
            break;
    // 去掉右边与中间相同值数的个数
    for(int i=mid+1; i<n; i++)
        if(val[i] == val[mid])
            rightcount--;
        else
            break;

    // 输出结果
    if(leftcount == rightcount)
        cout << val[mid] << endl;
    else
        cout << -1 << endl;

    return 0;
}



使用函数lower_bound()和upper_bound()的版本,提交后得100分的C++语言程序如下:

/* CCF201612-1 中间数 */

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1000;
int val[N];

int main()
{
    int n;

    // 输入数据
    cin >> n;
    for(int i=0; i<n; i++)
        cin >> val[i];

    // 排序
    sort(val, val+n);

    // 找出中间数
    int mid = val[n / 2];
    int lb = lower_bound(val, val + n, mid) - val;
    int ub = upper_bound(val, val + n, mid) - val;


    // 输出结果
    if(n - ub == lb)
        cout << mid << endl;
    else
        cout << -1 << endl;

    return 0;
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324882799&siteId=291194637