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

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值