Codeforces Round #440 (Div. 2) B. Maximum of Maximums of Minimums

来源:互联网 发布:甲骨文云计算大会 编辑:程序博客网 时间:2024/06/01 17:51

B. Maximum of Maximums of Minimums

Problem Statement

    You are given an array a1, a2, …, an consisting of n integers, and an integer k. You have to split the array into exactly k non-empty subsegments. You’ll then compute the minimum integer on each subsegment, and take the maximum integer over the k obtained minimums. What is the maximum possible integer you can get?
    Definitions of subsegment and array splitting are given in notes.

Input

    The first line contains two integers n and k (1 ≤ k ≤ n ≤  105) — the size of the array a and the number of subsegments you have to split the array to.
    The second line contains n integers a1,  a2,  …,  an ( - 109  ≤  ai ≤  109).

Output

    Print single integer — the maximum possible integer you can get if you split the array into k non-empty subsegments and take maximum of minimums on the subsegments.

Examples

Example 1
    Input
        5 2
        1 2 3 4 5
    Output
        5
Example 2
    Input
        5 1
        -4 -5 -3 -2 -1
    Output
        -5

Note

    A subsegment [l,  r] (l ≤ r) of array a is the sequence al,  al+1,  …,  ar.
    Splitting of array a of n elements into k subsegments [l1, r1], [l2, r2], …, [lk, rk] (l1 = 1, rk = n, li = ri - 1 + 1 for all i > 1) is k sequences (al1, …, ar1), …, (alk, …, ark).
    In the first example you should split the array into subsegments [1, 4] and [5, 5] that results in sequences (1, 2, 3, 4) and (5). The minimums are min(1, 2, 3, 4) = 1 and min(5) = 5. The resulting maximum is max(1, 5) = 5. It is obvious that you can’t reach greater result.
    In the second example the only option you have is to split the array into one subsegment [1, 5], that results in one sequence ( - 4,  - 5,  - 3,  - 2,  - 1). The only minimum is min( - 4,  - 5,  - 3,  - 2,  - 1) =  - 5. The resulting maximum is  - 5.

题意

    给一组整数,把这个数组切成 k 段,要求这 k 段每段中所有数字的最小值的最大值最大,求出这个最大值。

思路

    这题可以通过分类讨论来做:当k=1时,很显然,输出数组的最小值就行了;当k>2时,也很显然,只要输出数组的最大值就行了,因为分成大于等于3段的数组,我们可以将最大值单独分成一份,这样不管其他怎么分答案永远是最大值。当k=2的时候,我们可以记录一下1~i和i~n两段的最小值,然后O(n)扫一遍就好了..不过k=2的时候还有更简单的方法,就是直接输出max(a[1],a[n])。可以发现,两段中必有一段含有数列的最小值,这一段的最小值是确定的。而这两段肯定分别包含一个端点,因此另一段的最小值不会小于端点值。可以发现,这个值一定能取到。因此,输出两个端点的最大值即可。

Code

#pragma GCC optimize(3)#include<bits/stdc++.h>using namespace std;typedef long long ll;inline void readInt(int &x) {    x=0;int f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();    x*=f;}inline void readLong(ll &x) {    x=0;int f=1;char ch=getchar();    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();    x*=f;}/*================Header Template==============*/int n,k;int arr[100002];int main() {    cin>>n>>k;    for(int i=1;i<=n;i++)        cin>>arr[i];    if(k==1) {        int mi=1e9+7;        for(int i=1;i<=n;i++)            mi=min(mi,arr[i]);        cout<<mi<<endl;        return 0;    }    else if(k==2) {        int mipre[100002],mxpre[100002];        for(int i=0;i<=n+1;i++) {            mipre[i]=1e9+7;            mxpre[i]=1e9+7;        }        for(int i=1;i<=n;i++)            mipre[i]=min(mipre[i-1],arr[i]);        for(int i=n;i>=1;i--)            mxpre[i]=min(mxpre[i+1],arr[i]);        int tmp=-(1e9+7);        for(int i=1;i<=n-1;i++)            tmp=max(tmp,max(mipre[i],mxpre[i+1]));        cout<<tmp<<endl;        return 0;    }    else {        int mx=-(1e9+7);        for(int i=1;i<=n;i++)            mx=max(mx,arr[i]);        cout<<mx<<endl;        return 0;    }}
阅读全文
0 0