T145305 【2020.8.24 NOIP simulation competition】Select the number

T145305 【2020.8.24 NOIP simulation competition】Select the number

Title description
Given N numbers, we need to select R×C numbers among them, and fill them in an R×C matrix (R rows and C columns).

We first define a function D(i) to represent the difference between the largest number and the smallest number in the i-th row. For the entire matrix, define F as the maximum value of D(i) (1≤i≤R) in the matrix.

We need the smallest value of F. Can you find the smallest possible value of F?

Input format The
first line gives 3 integers N, R, C, corresponding to the parameters described in the title.
There are N integers in the next line, representing N number P_i that can be selected

Output format
One line of output indicates the least possible FF value.

Input and output sample
input

7 2 3
170 205 225 190 260 225 160

Output

30

Note/tip
For 50% of data: 1≤N≤1000
For all data, 1 ≤ R, C ≤ \le R,C\leR,C 104,R × \times × C ≤ N ≤ 5 ∗ 1 0 5 C \ le N \ le5 * 10 ^ 5CN5105,0 < P i ≤ 1 0 9 P_i \le 10^9 Pi109

Idea:
We can adopt the idea of ​​dichotomy. Of course, for dichotomy, we must make the array monotonic. So we sort the array in ascending order.
We use the binary enumeration f.
Then how to judge whether it is possible?
Determine whether the number is less than the situation obtained by the binary division, and
judge that the value of f can be made into an R row.
That's it.

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#define ll long long
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=5e5+10;
ll n,r,c,a[N],ans,ht[N];
bool check(ll x)
{
    
    
    for (ll i=0;i<=c;i++) ht[i]=0;
    for (ll i=c;i<=n;i++)
    {
    
    
        ht[i]=ht[i-1];
        if (a[i]-a[i-c+1]<=x) ht[i]=ht[i-c]+1;
    }
    return ht[n]>=r?true:false;
}
int main()
{
    
    
	scanf("%lld%lld%lld",&n,&r,&c);
	for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
	sort(a+1,a+1+n);
	ll l=0,r=999999999;
	while(l<=r)
	{
    
    
		ll mid=(l+r)/2;
		if(check(mid)) ans=mid,r=mid-1;
		else l=mid+1;
	}
	printf("%lld",ans);
	return 0;
}

Guess you like

Origin blog.csdn.net/bigwinner888/article/details/108200683