每日“二”題
十年OI一場空,不開longlong見祖宗
目錄
- 每日“二”題
- A
- B
A
題解:
最值問題,一個條件在變,考慮使用二分:
我們每次查詢一個可切的最大巧克力,二分判斷能不能這麼切即可。
C++程式碼
void solve() {
int n, k, l = 1, r = 0, ans;
cin >> n >> k;
vector<pair<int, int>>qwq(n);
for(auto &x : qwq) {
cin >> x.first >> x.second;
int mx = max(x.first, x.second);
r = max(mx, r); //確定一個二分最大值,這裡其實也可以給一個很大的值減少程式碼量
}
while(l <= r) { //二分答案
int mid = l + r >> 1;
//check() 按一般背的板子來是寫一個 check() 我這裡為了方便直接寫這裡面了
int tot = 0;
for(auto x : qwq)tot += (x.first / mid) * (x.second / mid);
if(tot < k)r = mid - 1;
//check()截止
else l = mid + 1;
}
cout << r;
}
B
題解:
我們建立一個字首和陣列,接著看一下里面同餘的有幾個數即可
(為什麼同餘就說明有倍數呢?這是因為:
如果兩數之間和不為k倍數,則餘數一定不同,容易可得自行證明吧XD
C++程式碼
void solve() {
ll n, k, i, j,ans=0;
cin >> n >> k;
vector<ll>qwq(n + 1); //字首和陣列
vector<ll>qaq(k + 1); //等效雜湊表->map
for(i = 1;i <= n;++i) {
cin >> qwq[i];
//qwq[i] %= k; 這個並不重要,可以省略
qwq[i] += qwq[i - 1]; //字首和,解題關鍵1
}
// 試了下暴力,並不能過
for(i = 0;i <= n;++i)ans += qaq[qwq[i] % k]++; //同餘,解題關鍵2
cout << ans;
}