1、最少垃圾处理站数
数组表示所有垃圾点垃圾数,每次处理站可以减少某个站一半,需要减少到总量的一半以下,求嘴上的站数。
思路:大顶堆排序,每次顶除二再重排
void heapify(vector<double>& arr, int n, int i)
{
if (i > n) {
return;
}
int left = i*2+1;
int right = i*2+2;
int max_index = i;
if (left < n && arr[left] >= arr[max_index]) {
max_index = left;
}
if (right < n && arr[right] >= arr[max_index]) {
max_index = right;
}
if (max_index != i) {
swap(arr[i], arr[max_index]);
heapify(arr, n, max_index);
}
}
void buildHeap(vector<double>& arr)
{
int n = (int)arr.size();
for (int i = (n-2)/2; i >= 0; i--)
{
heapify(arr, n, i);
}
}
int solution(vector<int> A) {
vector<double> arr(A.size(), 0);
double sum = 0;
for (int i=0; i<A.size(); i++) {
sum += A[i];
arr[i] = A[i];
}
buildHeap(arr);
double now_sum = 0;
int res = 0;
while (now_sum*2 < sum) {
now_sum += arr[0]/2;
arr[0] = arr[0]/2;
heapify(arr, arr.size(), 0);
res++;
}
return res;
}
2、分数求和为1
两个数组A和B,表示所有分数依次分子和分母。求有多少种可能,任取两个相加和为1
思路:哈希表+gcd
int gcd(int a, int b){
while (b) {
int r = a % b;
a = b;
b = r;
}
return a;
}
int solution(vector<int> &X, vector<int> &Y) {
map<string, int> mp;
int res = 0;
int MOD = 1000000007;
for (int i=0; i<X.size(); i++) {
int a = X[i], b = Y[i];
int tmp = gcd(a,b);
a = a/tmp;
b = b/tmp;
string key = to_string(a) + "/" + to_string(b);
string other = to_string(b-a) + "/" + to_string(b);
if (mp.find(other) != mp.end()) {
res += mp[other];
res %= MOD;
}
if (mp.find(key) == mp.end()) {
mp[key] = 1;
} else {
mp[key]++;
}
}
return res;
}
3、康复训练
病人做康复训练,共需要做X次。一共有n天可以选择,每次耗费为A[i]。每次完成训练后必须在Y天后继续训练,求最小成本。
思路:前缀和,分组
int solution(vector<int>& A, int X, int Y) {
vector<int> preSum(A.size()+1, 0);
for (int i=0; i<A.size(); i++) {
if (i+1-Y >= 0) {
preSum[i+1] = A[i] + preSum[i+1-Y];
} else {
preSum[i+1] = A[i];
}
}
int res = INT_MAX;
for (int i=(X-1)*Y+1; i<=A.size(); i++) {
int tmp = 0;
if (i < X*Y) {
tmp = preSum[0];
} else {
tmp = preSum[i - X*Y];
}
if (res > preSum[i] - tmp) {
res = preSum[i] - tmp;
}
}
return res;
}