题目描述
入职后,导师会请你吃饭,你选择了火锅。
火锅里会在不同时间下很多菜。
不同食材要煮不同的时间,才能变得刚好合适。
你希望吃到最多的刚好合适的菜,但你的手速不够快,用m代表手速,每次下手捞菜后至少要过m秒才能再捞(每次只能捞一个)。
那么用最合理的策略,最多能吃到多少刚好合适的菜?
输入描述
第一行两个整数n,m,其中n代表往锅里下的菜的个数,m代表手速。(1 < n, m < 1000)
接下来有n行,每行有两个数x,y代表第x秒下的菜过y秒才能变得刚好合适。(1 < x, y < 1000)
输出描述
输出一个整数代表用最合理的策略,最多能吃到刚好合适的菜的数量。
用例
| 输入 | 2 1 1 2 2 1 |
|---|---|
| 输出 | 1 |
| 说明 | 无 |
参考
华为OD机试备考攻略 以及题库目录分值说明 考点说明
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<string> lines; // 存储输入的每一行
int n = 0, m = 0; // n表示菜的数量,m表示两道菜之间的最小间隔时间
while (true) { // 循环读取每一行输入
string line;
getline(cin, line);
lines.push_back(line); // 将读取的行添加到列表中
if (lines.size() == 1) { // 如果是第一行输入,则解析出n和m
size_t pos = line.find(" ");
n = stoi(line.substr(0, pos));
m = stoi(line.substr(pos + 1));
}
if (n > 0 && lines.size() == n + 1) { // 如果已经读取了n行菜品信息,则开始处理
lines.erase(lines.begin()); // 移除第一行输入(即n和m)
vector<pair<int, int>> cais; // 存储每道菜的烹饪时间和上桌时间
for (const string& str : lines) { // 循环解析每道菜的信息
size_t pos = str.find(" ");
int cookTime = stoi(str.substr(0, pos)); // 第一个元素表示烹饪时间
int serveTime = stoi(str.substr(pos + 1)); // 第二个元素表示上桌时间
cais.emplace_back(cookTime, serveTime); // 将菜的信息添加到列表中
}
vector<int> suits; // 记录每个菜刚好合适的时间点
for (const auto& cai : cais) {
suits.push_back(cai.first + cai.second); // 合适时间点等于烹饪时间加上上桌时间
}
sort(suits.begin(), suits.end()); // 对每个菜的合适时间点进行排序
int count = 1; // 第1个合适的菜必吃
int lastSuitTime = suits.front(); // 记录上一次捞菜的时间点
for (size_t i = 1; i < suits.size(); i++) { // 从第2个合适的菜开始循环
int currentSuitTime = suits[i]; // 当前菜的合适时间点
if (currentSuitTime >= lastSuitTime + m) { // 如果想要捞本次合适的菜,则必须要与上次捞菜的时间差大于等于m
count++;
lastSuitTime = currentSuitTime; // 如果本次捞了菜,则更新缓存本次捞菜的时间点
}
}
cout << count << endl; // 最多能吃几道菜
break; // 处理完毕,退出循环
}
}
return 0;
}