【JZOJ4790】选数问题

来源:互联网 发布:即时通讯办公软件 编辑:程序博客网 时间:2024/06/08 11:38

Description

在麦克雷的面前有N个数,以及一个R*C的矩阵。现在他的任务是从N个数中取出R*C个,并填入这个矩阵中。矩阵每一行的法值为本行最大值与最小值的差,而整个矩阵的法值为每一行的法值的最大值。现在,麦克雷想知道矩阵的最小法值是多少。

Solution

最优方案肯定是排序后,每一行连着选C个,然后按顺序选出R行即可。

于是二分判断解决。

Code

#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#define fo(i,j,k) for(int i=j;i<=k;i++)#define fd(i,j,k) for(int i=j;i>=k;i--)#define N 500001using namespace std;int a[N];int n,r,c,qq=0;bool check(int mid){    int cnt=0,p=0;    while(p+1<=n-c+1)    {        p++;        if(a[p+c-1]-a[p]<=mid)        {            p+=c-1;            cnt++;        }    }    if(cnt>=r) return true;    return false;}int main(){    cin>>n>>r>>c;    fo(i,1,n) scanf("%d",&a[i]);    sort(a+1,a+n+1);    int l=0,r=a[n]-a[1];    while(l+1<r)    {        int mid=(l+r)/2;        if(check(mid)) r=mid;        else l=mid;    }    if(check(l)) cout<<l;    else cout<<r;}
1 0
原创粉丝点击