《P3029 [USACO11NOV] Cow Lineup S》
题目描述
问题描述
农民约翰雇佣了一位专业摄影师来拍摄他的一些奶牛。由于约翰的奶牛代表了多种不同的品种,他希望照片中至少包含他牛群中每种不同品种的一头奶牛。
约翰的 N 头奶牛都站在一条线上的不同位置,每头奶牛的位置由一个整数(即其 x 坐标)和一个整数品种 ID 描述。约翰计划拍摄一段连续的奶牛范围。该照片的成本等于其大小——即照片中奶牛的最大和最小 x 坐标之间的差。
请帮助约翰计算出一张照片的最小成本,其中至少包含约翰牛群中每种不同品种的一头奶牛。
输入格式
- 第 1 行:奶牛的数量 N(1≤N≤50,000)。
- 第 2 行到第 1+N 行:每行包含两个用空格分隔的正整数,分别指定一头奶牛的 x 坐标和品种 ID。这两个数字的最大值为 109。
输出格式
- 第 1 行:包含每种不同品种 ID 的照片的最小成本。
显示翻译
题意翻译
输入输出样例
输入 #1复制
6 25 7 26 1 15 1 22 3 20 1 30 1
输出 #1复制
4
说明/提示
有 6 头奶牛,位置分别为 25、26、15、22、20、30,品种 ID 分别为 7、1、1、3、1、1。
从 x=22 到 x=26 的范围(总大小为 4)包含了约翰的牛群中每种不同的品种 ID:1、3 和 7。
代码实现:
#include<bits/stdc++.h>
using namespace std;
// 定义结构体来存储对象信息
struct Object {
int position;
int category;
};
// 定义对象数组
Object objects[70000];
// 定义变量用于存储结果、种类总数、对象数量、当前种类数和尾指针
int result = 2e9, totalCategories, numObjects, currentCategories, endIndex;
// 定义两个map,一个用于记录每种对象的数量,另一个用于标记对象是否出现过
map<int, int> categoryCount;
map<int, bool> categoryExists;
// 比较函数,用于按位置对对象进行排序
bool compareObjects(Object a, Object b) {
return a.position < b.position;
}
int main() {
// 读取对象的数量
cin >> numObjects;
// 读取每个对象的位置和种类,并统计种类总数
for (int i = 1; i <= numObjects; i++) {
cin >> objects[i].position >> objects[i].category;
if (!categoryExists[objects[i].category]) {
totalCategories++;
categoryExists[objects[i].category] = true;
}
}
// 按位置对对象进行排序
sort(objects + 1, objects + numObjects + 1, compareObjects);
// 初始化尾指针、第一个对象的种类计数和当前种类数
endIndex = 1;
categoryCount[objects[1].category]++;
currentCategories = 1;
// 使用滑动窗口算法来寻找包含所有种类的最小区间
for (int startIndex = 1; startIndex <= numObjects; startIndex++) {
// 移动尾指针,直到包含所有种类或者尾指针到达数组末尾
while (currentCategories < totalCategories && endIndex < numObjects) {
endIndex++;
categoryCount[objects[endIndex].category]++;
if (categoryCount[objects[endIndex].category] == 1) {
currentCategories++;
}
}
// 如果当前区间包含所有种类,更新结果
if (currentCategories == totalCategories) {
result = min(result, objects[endIndex].position - objects[startIndex].position);
}
// 移动头指针,更新种类计数和当前种类数
categoryCount[objects[startIndex].category]--;
if (categoryCount[objects[startIndex].category] == 0) {
currentCategories--;
}
}
// 输出结果
cout << result;
return 0;
}