傳送門
要保護環境
木材廠有一些原木,現在想把這些木頭切割成一些長度相同的小段木頭(木頭有可能有剩餘),需要得到的小段的數目是給定的。當然,我們希望得到的小段木頭越長越好,你的任務是計算能夠得到的小段木頭的最大長度。木頭長度的單位是cm。原木的長度都是正整數,我們要求切割得到的小段木頭的長度也是正整數。
例如有兩根原木長度分別為11和21,要求切割成到等長的6段,很明顯能切割出來的小段木頭長度最長為5.
第一行是兩個正整數n和k(1 ≤ n ≤ 100000,1 ≤ k ≤ 100000000),n是原木的數目,k是需要得到的小段的數目。
接下來的n行,每行有乙個1到100000000之間的正整數,表示一根原木的長度。
能夠切割得到的小段的最大長度。如果連1cm長的小段都切不出來,輸出"0"。
3 7
232124
456
114
二分答案基礎好題。
思路非常簡單,二分切出的小段長度即可。
二分的左邊界l顯然是0,那麼右邊界呢?是最短的木棍嗎?
我們來看這樣一組資料
3 6
1121
1
如果我們把右邊界r定為最短的木棍1,顯然得不到最優解。最優解根本就不會用到長度為1的木棍,所以r定這個是不行的。
我們不必拘泥於最短的木棍,因為木棍可以扔掉。所以我們可以把r大膽的定到乙個位置,使得這個位置是有可能有解的,但是再+1就沒解的值。
我猜你一定想到了,沒錯,就是把所有木棍的長度加起來/k。解最高只能是這個值了,再高就不行了,因為你沒有那麼多原木。
邊界定了,再來看看check函式。
check函式其實也十分簡單,模擬一下就行,通過擷取的長度算出需要多少段,再看看切出的段數能不能到k。**如下:
bool check(int l)
到這裡,我們就可以拿80分了,事實上我們還有一種情況沒有判斷:一根木棍都截不下來。這種情況下得到的r是0,mid就會是0,而check函式中涉及到了除以mid的操作(mid相當於函式中的l),所以你懂得。。
所以我們要來個特判,如果sum / k < 1,說明根本截不下來,這個時候直接輸出0,結束程式。這樣就可拿到滿分啦。
**走起。
/*
* @author: crab-in-the-northeast
* @date: 2020-06-16 01:01:11
* @last modified by: crab-in-the-northeast
* @last modified time: 2020-06-16 01:06:58
*/#include #include const int maxn = 100005;
int n, k;
int a[maxn];
bool check(int l)
int main()
if (sum / k < 1)
r = sum / k;
while (l <= r)
std :: cout << l - 1 << std :: endl;
return 0;
}
評測記錄 LUOGU P2440 木材加工
思路 二分,對莫乙個長度計算總段數,計算出的總段數與題意比較,若總段數小於題目要求,長度減小,反之,長度變大 時間複雜度 o nlogn include include using namespace std typedef long long ll ll a 100050 ll n,k 判斷長度為...
P2440 木材加工
要保護環境 木材廠有一些原木,現在想把這些木頭切割成一些長度相同的小段木頭 木頭有可能有剩餘 需要得到的小段的數目是給定的。當然,我們希望得到的小段木頭越長越好,你的任務是計算能夠得到的小段木頭的最大長度。木頭長度的單位是cm。原木的長度都是正整數,我們要求切割得到的小段木頭的長度也是正整數。例如有...
P2440 木材加工
木材廠有一些原木,現在想把這些木頭切割成一些長度相同的小段木頭 木頭有可能有剩餘 需要得到的小段的數目是給定的。當然,我們希望得到的小段木頭越長越好,你的任務是計算能夠得到的小段木頭的最大長度。木頭長度的單位是cm。原木的長度都是正整數,我們要求切割得到的小段木頭的長度也是正整數。例如有兩根原木長度...