切蛋糕问题:
一个矩形的蛋糕,长为X,宽为Y,沿着X和Y轴各切了刀,形成(N + 1) ^ 2 小块。求面积第K大的块的面积。
函数头部:
int solution(int X, int Y, int K, vector<int> &A, vector<int> &B);
数据范围:
N [1..40000];
X, Y [2..4 * 10 ^ 8]
相邻两刀之间的距离(包括刀和边界的距离)<=10000
要求复杂度时间: Nlog(N + X + Y)
空间: O(N)
思路: 其实这个题就是杨氏矩阵行列乘积的最大值…… 有复杂度更底的算法…… 对于这个复杂度,用二分就行了。。。当然X,Y要先排序。
二分的思路很简单,从最小块到最大块枚举一个整数,然后看一下它氏第几大的,看它是第几大的时候,可以利用类似于2-sum的方法O(N)实现。
代码:
// you can use includes, for example: // #include <algorithm> // you can write to stdout for debugging purposes, e.g. // cout << "this is a debug message" << endl; #include <algorithm> int cal(vector<int> &a,vector<int> &b,long long num) { int n = a.size(), ans = 0; for(int i = 0, j = n - 1; i < n; ++i) { for(; (j >= 0) && (a[i] * b[j] > num) ; --j) ; ans += n - 1 - j; } return ans; } int bs(vector<int> &a,vector<int> &b,int k) { int n = a.size(), left = a[0] * b[0], right = a[n - 1] * b[n - 1]; while (left <= right) { int mid = (left + right) >> 1; if (cal(a, b, mid) >= k) { left = mid + 1; } else { right = mid - 1; } } return right + 1; } int solution(int X, int Y, int K, vector<int> &A, vector<int> &B) { // write your code in C++11 A.push_back(X); B.push_back(Y); for (int i = A.size() - 1; i > 0; --i) { A[i] -= A[i - 1]; B[i] -= B[i - 1]; } sort(A.begin(),A.end()); sort(B.begin(),B.end()); return bs(A, B, K); }