小招喵喜歡喫喵糧。這裏有 N 堆喵糧,第 i 堆中有 p[i] 粒喵糧。喵主人離開了,將在 H 小時後回來。
小招喵可以決定她喫喵糧的速度 K (單位:粒/小時)。每個小時,她將會選擇一堆喵糧,從中喫掉 K 粒。如果這堆喵糧少於 K 粒,她將喫掉這堆的所有喵糧,然後這一小時內不會再喫更多的喵糧。
小招喵喜歡慢慢喫,但仍然想在喵主人回來前喫掉所有的喵糧。
返回她可以在 H 小時內喫掉所有喵糧的最小速度 K(K 爲整數)。
思路分析:
首先,看到題目比較長,要從題目中提取到有效信息。N堆,要喫H小時,每小時喫K粒,如果一堆一小時喫不完,下一個小時繼續喫,如果一個小時不夠喫,這個小時之內不喫別的堆。
提供一種思路,用貪心和二分查找的方式。首先:最快的進食速度是,所有堆當中粒數最大的就是。
最慢的進食速度是,所有的粒數之和除以主人回來的時間,就是最慢的進食時間。
但是,直接計算的最慢的進食時間不一定符合實際,我們得出來最快和最慢的進食時間,然後就用二分查找的方式,以最小和最大的速度爲區間。求出中間值,用中間值去實際的模擬,最後得到最慢的進食速度。
#include <string>
#include <vector>
#include <iostream>
#include <istream>
#include <algorithm>
#include <sstream>
using namespace std;
vector<int> arr;
int H, tmp, sum = 0, mmax = 0, res, mmin;
bool solve(int x, int H) {
int res = 0;
for (int i = 0; i < arr.size(); i++) {
res += (arr[i] % x == 0) ? arr[i] / x : arr[i] / x + 1;
}
return res <= H;
}
int mainfrefdr()
{
string line;
getline(cin, line);
istringstream iss(line);
while (iss >> tmp) {
arr.push_back(tmp);
mmax = max(mmax, tmp);
sum += tmp;
}
scanf("\n%d", &H);
mmin = (sum % H == 0) ? sum / H : sum / H + 1;
while (mmin < mmax) {
res = (mmin + mmax) / 2;
if (solve(res, H)) mmax = res;//滿足條件時 將右邊屆設爲中間值
else mmin = res + 1;
if (solve(mmin, H)) break;//左邊界滿足時 終止
}
cout << mmin << endl;//結果爲左邊界
system("pause");
return 0;
}