FJ的N头牛正沿着一个笔直的围栏放牧。奶牛i站在位置X_iX i 上,其高度为H_iH i 。奶牛感觉“拥挤”,是在一头牛的左边D距离内(包括边界D)至少有她两倍的高度的牛存在,还有她右边D距离内(包括边界D)至少有她两倍的高度的牛存在,所以这头牛就感觉到了“拥挤”。由于拥挤的奶牛产奶量少,农民约翰想减少拥挤的奶牛数量。请帮助他。 Input 第1行:两个用空格隔开的整数,N和D,意义如题目描述; 第2到N+1行:第i+1行第i头奶牛的信息,包含两个整数X_iX i 和H_iH i ,N头奶牛的位置互不相同。 用单调队列
时间: 2024-04-14 07:25:59 浏览: 92
以下是使用单调队列解决这个问题的C++代码示例:
```cpp
#include <iostream>
#include <vector>
#include <deque>
struct Cow {
int position;
int height;
};
int countCrowdedCows(const std::vector<Cow>& cows, int distance) {
int n = cows.size();
std::vector<int> leftCount(n, 0); // 记录每头奶牛左边拥挤的牛的数量
std::vector<int> rightCount(n, 0); // 记录每头奶牛右边拥挤的牛的数量
std::deque<int> leftDeque, rightDeque; // 单调递减的双端队列,存储奶牛的下标
// 计算左边拥挤的牛的数量
for (int i = 0; i < n; i++) {
while (!leftDeque.empty() && cows[leftDeque.back()].height < 2 * cows[i].height) {
leftDeque.pop_back();
}
leftDeque.push_back(i);
if (cows[i].position - cows[leftDeque.front()].position > distance) {
leftDeque.pop_front();
}
leftCount[i] = i - leftDeque.front();
}
// 计算右边拥挤的牛的数量
for (int i = n - 1; i >= 0; i--) {
while (!rightDeque.empty() && cows[rightDeque.back()].height < 2 * cows[i].height) {
rightDeque.pop_back();
}
rightDeque.push_back(i);
if (cows[rightDeque.front()].position - cows[i].position > distance) {
rightDeque.pop_front();
}
rightCount[i] = rightDeque.front() - i;
}
int crowdedCount = 0;
for (int i = 0; i < n; i++) {
if (leftCount[i] >= 2 && rightCount[i] >= 2) {
crowdedCount++;
}
}
return crowdedCount;
}
int main() {
int N, D;
std::cin >> N >> D;
std::vector<Cow> cows(N);
for (int i = 0; i < N; i++) {
std::cin >> cows[i].position >> cows[i].height;
}
int crowdedCount = countCrowdedCows(cows, D);
std::cout << crowdedCount << std::endl;
return 0;
}
```
这段代码使用了两个单调递减的双端队列 `leftDeque` 和 `rightDeque`,分别用来计算每头奶牛左边和右边拥挤的牛的数量。首先,遍历奶牛数组,通过维护 `leftDeque` 计算每头奶牛左边拥挤的牛的数量,并将结果保存在 `leftCount` 数组中。然后,倒序遍历奶牛数组,通过维护 `rightDeque` 计算每头奶牛右边拥挤的牛的数量,并将结果保存在 `rightCount` 数组中。最后,遍历奶牛数组,如果左边和右边拥挤的牛的数量都大于等于2,则将拥挤的奶牛数量加1。
希望这个代码能够帮助你解决问题!如果还有其他问题,请随时提问。
阅读全文