OD统一考试(C卷)
分值: 100分
题解: Java / Python / C++
现代计算机系统通常存在多级的存储设备,针对海量的 wordload 的优化的一种思路是将热点内存页优化先放到快速存储层级,这就需要对内存页进行冷热标记。
一种典型的方案是基于内存页的访问频次进行标记,如果统计窗口内访问次数大于等于设定阈值,要实现基于频次的冷热标记。内存页使用页框号作为标识。
第一行输入为 N
, 表示访存序列的记录条数, 0 < N
≤ 10000。
第二行为访问内存序列,空格间隔的 N
个内存页框号,页面号范围 0 ~ 65535,同一个页框号可能重复出现,出现的次数即为对应框号的频次。
第三行为热内存的频次阈值 T
,正整数范围 1 ≤ T ≤ 10000。
第一行为输出标记为热内存的内存页个数,如果没有被标记为热内存的,则输出 0。
如果第一行大于 0,则接下来按照访问频次降序输出内存页框号,一行一个,频次一样的页框号,页框号小的排前面。
输入:
10
1 2 1 2 1 2 1 2 1 2
5
输出:
2
1
2
说明:
内存页 1 和内存页 2 均被访问了5 次,达到了阈值5 ,因此热内存页有2个。内存页1 和内存页 2 的访问频次相等,页框号小的排前面。
输入:
5
1 2 3 4 5
3
输出:
0
说明:
从访问跟踪里面访问频次没有超过 3 的,因此热内存个数为 0。
这道题目首先需要统计每个内存页的访问频次,然后根据设定的阈值判断是否为热内存。接着,需要按照访问频次降序进行排序,同时对于频次相同的内存页,要按照页框号升序排序。
以下是解题思路的详细步骤:
- 使用一个
Map
(Java和Python)或者unordered_map
(C++)来统计每个内存页的访问频次。键为页框号,值为对应的频次。- 遍历输入的内存访问序列,更新频次统计。
- 遍历频次统计,将频次大于等于设定阈值的内存页加入一个列表。
- 对列表进行自定义排序,首先按照访问频次降序排序,然后在频次相同的情况下按照页框号升序排序。
- 输出结果,首先输出热内存的个数,然后按照排序后的顺序输出内存页框号。
import java.util.*;
/**
* @author code5bug
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
// 内存页访问次数
Map<Integer, Integer> cnt = new HashMap<>();
for (int i = 0; i < n; i++) {
int x = scanner.nextInt();
cnt.put(x, cnt.getOrDefault(x, 0) + 1);
}
int