一、Problem
窗外肉價飛漲,屋裏竈臺微響。便當店老闆在沉思中苦惱: 現在店裏的存貨還有nn條特製香腸,長度分別爲
如果能從它們中切割出 k 條長度相同的香腸的話,就能應付突如其來的奇怪的訂單
你能幫這位老闆計算一下這 k 條香腸每條最長能有多長嗎?
(答案保留小數點後兩位,規定1 單位長度的香腸最多可以切割成 100 份)
輸入
3 4
3 5 4
輸出
2.50
樣例解釋
第一根和第三根分別裁剪出一根2.50長度的繩子,第二根剪成2根2.50長度的繩子,剛好4根。
二、Solution
方法一:暴力
- 可選的長度一定在香腸長度區間 中,所以我們可以通過枚舉這裏面的區間中的每一個浮點數確定長度
- 從大到小枚舉,第一次可以將所有香腸一共切成 k 份的長度就是所求長度。
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
static class Solution {
double[] L;
int n, k;
boolean check(double l) {
int cnt = 0;
for (int i = 0; i < n; i++) {
int t = (int) (L[i] / l);
cnt += t;
if (cnt >= k)
return true;
}
return false;
}
void init() {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
n = sc.nextInt();
k = sc.nextInt();
L = new double[n];
for (int i = 0; i < n; i++) L[i] = sc.nextDouble();
Arrays.sort(L);
double max = L[n-1];
for (double i = max; i >= 0.01; i -= 0.01) {
if (check(i)) {
System.out.printf("%.2f", i);
return;
}
}
}
}
public static void main(String[] args) throws IOException {
Solution s = new Solution();
s.init();
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,
方法二:二分
- ,最小切分長度爲 1
- 當 mid 滿足切分要求時,應該貪心地右移左邊界,因爲可能會有更大 mid 在 l 的右邊。
2/20?什麼情況… 看上去沒什麼問題啊,都轉爲了整形,然後最後也轉爲了浮點數輸出了…
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
static class Solution {
int[] L;
int n, k;
boolean check(double l) {
int cnt = 0;
for (int i = 0; i < n; i++) {
int t = (int) (L[i] / l);
cnt += t;
if (cnt >= k)
return true;
}
return false;
}
void init() {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
n = sc.nextInt();k = sc.nextInt();L = new int[n];
for (int i = 0; i < n; i++) L[i] = (int)sc.nextDouble() * 100;
Arrays.sort(L);
int l = 1, r = L[n-1], res = 0;
while (l <= r) {
int mid = (l + r) >>> 1;
if (check(mid)) {
l = mid+1;
res = mid;
} else {
r = mid-1;
}
}
System.out.printf("%.2f", 1.0 * res / 100);
}
}
public static void main(String[] args) throws IOException {
Solution s = new Solution();
s.init();
}
}
老毛病,hh:輸入的時候先把浮點數轉爲整形,然後乘以 100,就算對了,也不好意思吧…
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
static class Solution {
int[] L;
int n, k;
boolean check(int l) {
int cnt = 0;
for (int i = 0; i < n; i++) {
cnt += L[i] / l;
if (cnt >= k)
return true;
}
return false;
}
void init() {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
n = sc.nextInt();k = sc.nextInt();L = new int[n];
int l = 1, r = 0, res = 0;
for (int i = 0; i < n; i++) {
L[i] = (int)(sc.nextDouble() * 100);
r = Math.max(L[i], r);
}
while (l <= r) {
int mid = (l + r) >>> 1;
if (check(mid)) {
l = mid + 1;
res = mid;
} else {
r = mid - 1;
}
}
System.out.printf("%.2f", 1.0 * res / 100);
}
}
public static void main(String[] args) throws IOException {
Solution s = new Solution();
s.init();
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,