题目描述
在麦克雷的面前有N个数,以及一个R*C的矩阵。现在他的任务是从N个数中取出 R*C 个,并填入这个矩阵中。矩阵每一行的法值为本行最大值与最小值的差,而整个矩阵的法值为每一行的法值的最大值。现在,麦克雷想知道矩阵的最小法值是多少。
输入
输入共两行。
第一行是三个整数:n,r,c。(r, c <= 104, r * c <= n< = 106)
第二行是 n 个整数 Pi。(0 < pi <= 109)
输出
输出一个整数,即满足条件的最小的法值。
样例输入
7 2 3
170 205 225 190 260 225 160
样例输出
30
思路: 暴力枚举(二分优化)
满足条件的法值 一定大于等于1, 小于 pi 中的最大值 Max。
从1~Max 这个范围内二分搜索最小的满足条件的法值。
bool judge(int v) ;
// v 作为最小法值能否成立
最坏时间复杂度我也算不出来,不过刚开始 judge 的循环次数接近于 r , 而后升高
#include <iostream> #include <algorithm> using namespace std; const int N = 1000100; int a[N]; int n, r, c; bool judge(int v) { // v 作为最小法值能否成立 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); // 排序 int left = 1, right = a[n]; int mid = (left+right)/2; while(left < right) { // 从1~Max 这个范围内二分搜索最小的满足条件的法值 // cout << mid << endl; if(judge(mid)) right = mid; else left = mid+1; mid = (right+left)/2; } cout << left << endl; return 0; }