蓝桥杯 : 分巧克力【第八届】【省赛】【B组】
思路:
每次枚举一种长度为x 的正方形。再带入每个矩形中计算每个矩形可以得到的最大块数
c
n
t
+
=
(
h
/
x
)
∗
(
l
/
x
)
cnt += (h/x) * (l/x)
cnt+=(h/x)∗(l/x)
复杂度分析: 如果两层循环枚举时间复杂度为 10^10 > 10^8 会超时。
为减少复杂度,可以使用二分查找代替长度x的枚举
即:在读入巧克力数据时,记录每块巧克力的边长最短的边 的最大值 max , 这样可以得到有效枚举的边界。ps:这是面积最大的巧克力只能分一块的情况
所以 我们在 1 - max 区间内进行二分查找
import java.awt.Frame;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.util.*;
public class Main{
static int n,m;
static int[][] c ;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s = br.readLine().split(" ");
n = Integer.parseInt(s[0]);
m = Integer.parseInt(s[1]);
c = new int[100010][2];
int max = 0;
for(int i =1 ; i <= n ; i++ ) {
s = br.readLine().split(" ");
c[i][0] = Integer.parseInt(s[0]);
c[i][1] = Integer.parseInt(s[1]);
max = Math.max(max,Math.min(c[i][1],c[i][0]) );
}
int l =1 , r = max;
int ans=0;
while(l <= r ) {
int mid = l + r >> 1;
if(check(mid)) {
ans = mid;
l = mid+1;
}
else r = mid-1;
}
System.out.println(ans);
}
static boolean check(int k) {
int cnt = 0 ;
for(int i = 1 ; i <= n ; i++ ) {
if(c[i][0] < k || c[i][1] < k ) continue;
cnt += (c[i][0] / k) * (c[i][1] / k);
if(cnt >= m ) return true;
}
return false ;
}
}