matrix

Topic description

There are N numbers and an R*C matrix in front of McCree. Now his task is to take R*C out of N numbers and fill in this matrix. The normal value of each row of the matrix is ​​the difference between the maximum value and the minimum value of the row, and the normal value of the entire matrix is ​​the maximum value of the normal value of each row. Now, McCree wants to know what the minimum normal value of the matrix is.

enter

Enter a total of two lines.

The first line is three integers: n, r, c. (r, c <= 10 4 , r * c <= n<= 10 6 )

The second line is n integers Pi. (0 < p i <= 10 9 )

output

Output an integer, the smallest normal value that satisfies the condition.

sample input

7 2 3
170 205 225 190 260 225 160

Sample output

30
Idea: Violent enumeration (binary optimization)

The normal value that satisfies the condition must be greater than or equal to 1 and less than the maximum value Max in pi.

From the range of 1~Max, binary search for the smallest normal value that satisfies the conditions.

bool judge(int v) ;

    // Whether v can be established as the minimum normal value

I can't calculate the worst time complexity, but the number of loops of the judge is close to r at the beginning, and then increases

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 1000100;
int a[N];

int n, r, c;

bool judge(int v) {
    // Whether v can be established as the minimum normal value
    int Count = 0;
    for(int i=c; i<=n; i++) {
        if(a[i]-a[i-c+1] <= v) {
            Count ++;
            if(Count >= r) {
                return true;
            }
            i = i+c-1;
        }
    }
    return false;
}

int main(){
    cin >> n >> r >> c;
    for(int i=1; i<=n; i++) {
            cin >> a[i];
    }
    sort(a+1, a+n+1); // sort

    int left = 1, right = a[n];
    int mid = (left+right)/2;

    while(left < right) {
     // From the range of 1~Max, binary search for the smallest normal value that satisfies the condition
     //   cout << mid << endl;
        if(judge(mid))
            right = mid;
        else
            left = mid+1;
        mid = (right+left)/2;
    }
    cout << left << endl;
    return 0;
}

Guess you like

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