關於E題, 我本來想著 把所有數字取模後排序, 然後二分找答案, 但是因為每次選擇某個數字後的刪除操作 需要用O(n), 就不知道怎麼實現了. 而且還可以用二分去找匹配的剩餘價值.
原來有multiset這個好工具, 基本能自動排序, 和支持刪除操作, stl大法好, 而且還支持lowerbound 和upperbound 操作,
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <math.h>
#include<deque>
#include<queue>
using namespace std;
typedef long long ll;
typedef long double ld;
vector<int> nums;
#include<iostream>
#include<set>
#include<vector>
using namespace std;
void work(){
ll n, k, x, ans = 0;
cin >> n >> k;
multiset<ll> s;
for(int i = 1; i<= n; i++){
cin >> x;
if(x >= k){
ans += x / k;
}
s.insert(x%k);
}
while(s.size()){
int v = *s.begin();
s.erase(s.begin());
if(s.end() != s.lower_bound(k - v)){
ans++;
s.erase(s.lower_bound(k - v));
}
}
cout << ans << endl;
}
int main(){
int t;
cin >> t;
while(t--){
work();
}
return 0;
}
實在方便, erase 操作, 會一次性把所有等於那個數值的東西刪除, 我們只需要刪除用了那個數, 所以每次拿begin()的位置, 然後刪除begin()的位置, 拿了的數字都要刪除, 然後就是記得用long long.