题目大意:
现有N头牛排成一排,这些牛其中包含M个种类,每个牛有对应的一维坐标。
现在要给这些牛拍一张照片,需要照片中出现所有种类的牛,且保证拍照范围最小。
分析:
最小完备(覆盖)子区间
可以用双指针(或双端队列)的尺取法
#include <unordered_map>
#include <array>
#include <cstdio>
#include <algorithm>
#include <limits>
#include <deque>
constexpr auto __MAX__ { static_cast<int>(1e5) * 5 };
typedef struct __node__ {
int coordinate {};
int categary {};
constexpr bool operator<(__node__ const & other) const noexcept
{ return coordinate < other.coordinate; }
} node;
std::unordered_map<int, int> counter {};
std::array<node, __MAX__> cows {};
std::deque<node> deq {};
int N {};
int result { std::numeric_limits<int>::max() };
int main(void) {
std::scanf("%d", &N);
for(int i {}; i < N; (void) ++ counter[cows[i ++].categary])
std::scanf("%d%d", &cows[i].coordinate, &cows[i].categary);
auto types { static_cast<int>(counter.size()) };
counter.clear();
std::sort(cows.begin(), cows.begin() + N);
int current {};
for(int i {}; i < N; ++i) {
if(! (counter[cows[i].categary] ++)) ++ current;
deq.push_back(cows[i]);
while(counter[deq.front().categary] - 1) {
-- counter[deq.front().categary];
deq.pop_front();
}
if(current == types) result = std::min(result, deq.back().coordinate - deq.front().coordinate);
}
std::printf("%d\n", result);
return 0;
}