一、题目描述
入职后,导师会请你吃饭,你选择了火锅。
火锅里会在不同时间下很多菜。
不同食材要煮不同的时间,才能变得刚好合适。你希望吃到最多的刚好合适的菜,但你的手速不够快,用m代表手速,每次下手捞菜后至少要过m庙才能在捞(每次只能捞一个)。
那么用最合理的策略,最多能吃到多少刚好合适的菜?
二、输入描述
第一行两个整数n,m,其中n代表往锅里下的菜的个数,m代表手速。
接下来有n行,每行有两个数x,y代表第x秒下的菜过y秒才能变得刚好合适。
(1 < n, m < 1000)
(1 < x, y < 1000)
三、输出描述
输出一个整数代表用最合理的策略,最多能吃到刚好合适的菜的数量。
四、解题思路
题目要求用最合理的策略,最多能吃到刚好合适的菜的数量。每道菜下锅后需要经过一定的时间才能变得刚好合适,而你的手速为 m,每次捞菜后至少需要过 m 秒才能再次捞菜。
- 读取输入的菜的数量 n 和手速 m;
- 创建两个长度为 n 的数组 arr1 和 arr2,分别用于存储每道菜的下锅时间和变得刚好合适所需的时间;
- 使用循环读取每道菜的下锅时间和变得刚好合适所需的时间,将其存入数组 arr1 和 arr2 中;
- 创建一个长度为 n 的数组 arrTime,用于存储每道菜可以吃到的时间;
- 遍历数组 arr1 和 arr2,将每道菜的下锅时间和变得刚好合适所需的时间相加,存入数组 arrTime 中;
- 对数组 arrTime 进行从小到大的排序,以便后续比较计算;
- 创建一个长度为 n 的数组 arrCount,用于记录每道菜是否可以吃到。初始时,将第一道菜的标记设置为 1;
- 使用变量 next 记录当前可以吃到的菜的索引,初始值为 0;
- 从第二道菜开始遍历数组 arrTime;
- 如果当前菜的时间大于等于 (前一道菜的时间 + m),表示可以吃到这道菜,将 arrCount 对应位置的标记设置为 1,并更新 next 的值为当前菜的索引;
- 使用变量 count 记录可以吃到的菜的数量,初始值为 0;
- 遍历数组 arrCount,如果某道菜的标记大于 0,表示可以吃到,将 count 自增;
- 输出 count,表示最多能吃到刚好合适的菜的数量。
五、Java算法源码
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNextInt()) {
int n = sc.nextInt();
int m = sc.nextInt();
int[] arr1 = new int[n];
int[] arr2 = new int[n];
for (int i = 0; i < n; i++) {
arr1[i] = sc.nextInt();
arr2[i] = sc.nextInt();
}
// 设置一个数组,存放每道菜可以吃到的时间。
int[] arrTime = new int[n];
for (int i = 0; i < n; i++) {
arrTime[i] = arr1[i] + arr2[i];
}
// 对数组进行从小到大进行排序,这样便于后面比较计算
Arrays.sort(arrTime);
// 新建一个数组,和数组arrTime对应,用于记录每道菜是否可以吃到,可以吃到标记加1.
int[] arrCount = new int[n];
int next = 0;
arrCount[0] = 1;
for (int i = 1; i < n; i++) {
if (arrTime[i] >= (arrTime[next] + m)) {
arrCount[i] = 1;
next = i;
}
}
int count = 0;
for (int i = 0; i < n; i++) {
if (arrCount[i] > 0) {
count++;
}
}
System.out.println(count);
}
}
六、效果展示
1、输入
2 1
1 2
2 1
2、输出
1
3、思路
一共下了两个菜,在第一秒下的菜需要到第三秒才能吃,在第二秒下的菜,也要第三秒才能吃,所以只能吃一个。
4、解题思路
- 菜可以吃的秒数=下菜的秒数x+菜适合吃的秒数y
- 第一个菜可以直接吃,后面的菜必须在吃的秒数上加上手速
- 同一秒的菜肯定只能吃一个
七、JavaScript算法源码
// 读取输入流,这里使用Node.js的readline模块
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// 主函数,读取输入并处理
async function main() {
let input;
while ((input = await rl.question('请输入两道菜的制作时间(每道两个整数,用空格分隔,多组输入以EOF结束): ')) {
// 将输入按空格分割成数组
const parts = input.split(' ').map(Number);
// 确保有正确的输入数量
if (parts.length !== 4) {
console.log('输入格式错误,请重新输入!');
continue;
}
const n = 2; // 因为题目中固定是两道菜
const m = parts[2]; // 第二道菜和第二道菜的间隔时间
const arr1 = [parts[0], parts[1]]; // 第一道菜的制作时间数组
const arr2 = [parts[3], parts[0] + m]; // 第二道菜的制作时间数组,第二道菜开始时间是第一道菜结束时间加间隔时间
// 设置一个数组,存放每道菜可以吃到的时间
const arrTime = [arr1[0] + arr1[1], arr2[0] + arr2[1]];
// 对数组进行从小到大排序
arrTime.sort((a, b) => a - b);
// 新建一个数组,记录每道菜是否可以吃到,可以吃到标记为true
const arrCount = [false, false];
let next = 0;
arrCount[0] = true; // 第一道菜总是可以吃到
if (arrTime[1] >= (arrTime[next] + m)) {
arrCount[1] = true; // 检查第二道菜是否可以吃到
}
// 计算可以吃到的菜的数量
let count = arrCount.filter(canEat => canEat).length;
// 输出结果
console.log(count);
}
// 关闭readline接口
rl.close();
}
// 调用主函数
main();
八、Python算法源码
# 导入需要的库
from typing import List
# 主函数
def main():
# 读取用户输入的行长度和数组数量
len_per_line = int(input("请输入每行的固定长度: "))
num_arrays = int(input("请输入整数数组的数目: "))
# 读取一行空行(nextInt后留下的)
input()
# 存储所有数组的列表
arrays = []
max_array_len = 0
total_len = 0
# 读取并处理每个数组
for _ in range(num_arrays):
# 读取一行,并按逗号分割成字符串列表
array_str = input().split(",")
arrays.append(array_str)
total_len += len(array_str)
max_array_len = max(max_array_len, len(array_str))
# 计算每个数组最多需要截取几次,即遍历次数
cycle = max_array_len // len_per_line
if max_array_len % len_per_line != 0:
cycle += 1
# 初始化结果列表
results = []
# 遍历所有截取次数
for i in range(cycle):
# 遍历所有数组
for array in arrays:
start = i * len_per_line
end = (i + 1) * len_per_line
size = len(array)
# 如果开始索引大于数组长度,说明该数组已经取完
if start > size - 1:
continue
# 结束索引最大为数组长度
if end > size:
end = size
# 取指定长度的子数组
results.extend(array[start:end])
# 输出结果,使用逗号连接
print(",".join(results))
# 调用主函数
if __name__ == "__main__":
main()
九、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
// 读取输入
int len, num;
scanf("%d %d", &len, &num);
getchar(); // 读取换行符
char ***arrays = (char ***)malloc(num * sizeof(char **));
int maxArrayLen = 0;
int totalLen = 0;
for (int i = 0; i < num; i++) {
char line[100];
fgets(line, sizeof(line), stdin);
char *token = strtok(line, ",");
int arrayLen = 0;
while (token != NULL) {
arrayLen++;
token = strtok(NULL, ",");
}
arrays[i] = (char **)malloc(arrayLen * sizeof(char *));
rewind(stdin); // 重置文件指针
fgets(line, sizeof(line), stdin);
token = strtok(line, ",");
for (int j = 0; j < arrayLen; j++) {
arrays[i][j] = token;
token = strtok(NULL, ",");
}
totalLen += arrayLen;
maxArrayLen = (arrayLen > maxArrayLen) ? arrayLen : maxArrayLen;
}
// 计算每个数组最多需要截取几次,即遍历次数
int cycle;
if (maxArrayLen % len == 0) {
cycle = maxArrayLen / len;
} else {
cycle = maxArrayLen / len + 1;
}
// 拼接结果数组
char **results = (char **)malloc(totalLen * sizeof(char *));
int start, end;
int resultIndex = 0;
for (int i = 0; i < cycle; i++) {
for (int j = 0; j < num; j++) {
start = i * len;
end = (i + 1) * len;
int size = arrayLen;
// 如果开始index已经大于数组最大,说明该数组取完了
if (start > size - 1) {
continue;
}
// 结束index最大为size
if (end > size) {
end = size;
}
// 取指定长度的子数组
for (int k = start; k < end; k++) {
results[resultIndex++] = arrays[j][k];
}
}
}
// 输出结果
for (int i = 0; i < resultIndex; i++) {
printf("%s", results[i]);
if (i < resultIndex - 1) {
printf(",");
}
}
printf("
");
// 释放内存
for (int i = 0; i < num; i++) {
free(arrays[i]);
}
free(arrays);
free(results);
return 0;
}
十、C++算法源码
#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <iterator>
int main() {
// 读取输入
int len, num;
std::cin >> len >> num; // 行每次读取的固定长度和整数数组的数目
std::cin.ignore(); // nextInt后有空行,先读取一次
std::vector<std::vector<std::string>> arrays(num);
int maxArrayLen = 0;
int totalLen = 0;
for (int i = 0; i < num; i++) {
std::string line;
std::getline(std::cin, line); // 读取一行
std::istringstream iss(line);
std::vector<std::string> array{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};
arrays[i] = array;
totalLen += array.size();
maxArrayLen = std::max(maxArrayLen, static_cast<int>(array.size()));
}
// 计算每个数组最多需要截取几次,即遍历次数
int cycle;
if (maxArrayLen % len == 0) {
cycle = maxArrayLen / len;
} else {
cycle = maxArrayLen / len + 1;
}
// 拼接结果数组
std::vector<std::string> results(totalLen);
int start, end;
for (int i = 0; i < cycle; i++) {
for (const auto& array : arrays) {
start = i * len;
end = (i + 1) * len;
int size = array.size();
// 如果开始index已经大于数组最大,说明该数组取完了
if (start > size - 1) {
continue;
}
// 结束index最大为size
if (end > size) {
end = size;
}
// 取指定长度的子数组
std::copy(array.begin() + start, array.begin() + end, std::back_inserter(results));
}
}
std::cout << std::join(",", results) << std::endl;
return 0;
}