E卷-推荐多样性-(200分)
E卷-刷题笔记合集🔗
推荐多样性
问题描述
推荐系统需要从多个列表中选择元素,以实现多样性推荐。系统需要返回 屏数据(窗口数量),每屏展示
个元素(窗口大小)。选择策略如下:
- 各个列表的元素需要做穿插处理,即先从第一个列表中为每屏选择一个元素,再从第二个列表中为每屏选择一个元素,依次类推。
- 每个列表的元素尽量均分为
份,如果不够
个,也要全部分配完。
选择过程示例:
- 从第一个列表中选择 4 条 0 1 2 3,分别放到 4 个窗口中
- 从第二个列表中选择 4 条 10 11 12 13,分别放到 4 个窗口中
- 从第三个列表中选择 4 条 20 21 22 23,分别放到 4 个窗口中
- 再从第一个列表中选择 4 条 4 5 6 7,分别放到 4 个窗口中
- 再从第一个列表中选择,由于数量不足 4 条,取剩下的 2 条,放到窗口 1 和窗口 2
- 再从第二个列表中选择,由于数量不足 4 条并且总的元素数达到窗口要求,取 18 19 放到窗口 3 和窗口 4
输入格式
第一行输入为 ,表示需要输出的窗口数量。
第二行输入为 ,表示每个窗口需要的元素数量。
之后的行数不定,每行表示一个列表的元素,元素之间以空格隔开。
输出格式
输出一行,包含 个整数,表示所有窗口中的元素,元素之间用空格分隔。输出顺序为先输出窗口 1 的元素列表,再输出窗口 2 的元素列表,以此类推。
样例输入
4
7
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
样例输出
0 10 20 4 14 24 8 1 11 21 5 15 25 9 2 12 22 6 16 26 18 3 13 23 7 17 27 19
样例解释
样例1 | 输出按照题目描述的规则,从三个输入列表中选择元素,填充 4 个窗口,每个窗口 7 个元素。输出顺序为窗口 1 到窗口 4 的所有元素。 |
数据范围
- 列表数量范围:
- 每个列表的元素数量范围:
题解
模拟
解题思路如下:
- 读取输入数据:读取窗口数量 N 和每个窗口的元素数量 K读取所有输入列表并存储
- 创建一个大小为 N * K 的数组来存储所有窗口的元素
- 使用循环来填充窗口数组:外层循环控制从哪个列表选择元素内层循环控制选择 N 个元素(每个窗口一个)当一个列表用完时,从列表集合中移除它当所有列表都遍历一遍后,重新从第一个列表开始
- 重新排列窗口数组,使其符合输出要求:创建一个新数组,按照每个窗口的顺序重新排列元素
- 输出结果
- Python
# 读取输入
n = int(input()) # 窗口数量
k = int(input()) # 每个窗口的元素数量
# 读取所有输入列表
lst = []
while True:
try:
lst.append(list(map(int, input().split())))
except EOFError:
break
# 创建窗口数组
win = [0] * (k * n)
idx = 0 # 窗口数组的索引
lvl = 0 # 当前处理的列表索引
# 填充窗口数组
while idx < len(win):
flg = False # 标记是否移除了一个列表
# 为每个窗口选择一个元素
for _ in range(n):
if idx >= len(win):
break
win[idx] = lst[lvl].pop(0)
idx += 1
# 如果当前列表为空,移除它
if not lst[lvl] and len(lst) > 1:
lst.pop(lvl)
lvl %= len(lst)
flg = True
# 如果没有移除列表,移动到下一个列表
if not flg:
lvl = (lvl + 1) % len(lst)
# 重新排列窗口数组以符合输出要求
ans = []
for j in range(n):
for i in range(k):
if i * n + j < len(win):
ans.append(win[i * n + j])
# 输出结果
print(" ".join(map(str, ans)))
- Cpp
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int main() {
int n, k;
cin >> n >> k; // 读取窗口数量和每个窗口的元素数量
cin.ignore(); // 忽略换行符
vector<vector<int>> lst; // 存储所有输入列表
string line;
while (getline(cin, line)) {
if (line.empty()) break;
istringstream iss(line);
vector<int> temp;
int num;
while (iss >> num) {
temp.push_back(num);
}
lst.push_back(temp);
}
vector<int> win(k * n, 0); // 创建窗口数组
int idx = 0; // 窗口数组的索引
int lvl = 0; // 当前处理的列表索引
// 填充窗口数组
while (idx < win.size()) {
bool flg = false; // 标记是否移除了一个列表
// 为每个窗口选择一个元素
for (int i = 0; i < n && idx < win.size(); ++i) {
win[idx] = lst[lvl][0];
lst[lvl].erase(lst[lvl].begin());
idx++;
// 如果当前列表为空,移除它
if (lst[lvl].empty() && lst.size() > 1) {
lst.erase(lst.begin() + lvl);
lvl %= lst.size();
flg = true;
}
}
// 如果没有移除列表,移动到下一个列表
if (!flg) {
lvl = (lvl + 1) % lst.size();
}
}
// 重新排列窗口数组以符合输出要求
vector<int> ans;
for (int j = 0; j < n; ++j) {
for (int i = 0; i < k; ++i) {
if (i * n + j < win.size()) {
ans.push_back(win[i * n + j]);
}
}
}
// 输出结果
for (int i = 0; i < ans.size(); ++i) {
cout << ans[i];
if (i < ans.size() - 1) cout << " ";
}
cout << endl;
return 0;
}
- Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取输入
int n = scanner.nextInt(); // 窗口数量
int k = scanner.nextInt(); //
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
算法刷题笔记 文章被收录于专栏
本专栏收集并整理了一些刷题笔记