2023年春季PAT乙级 B-5 LRU-K 缓存

B-5 LRU-K 缓存

分数 25

LRU 全称为 LeastRecently Used,即“最近最少使用”。LRU 缓存机制是指,当缓存满了,而缓存区外面的一个新数据被调用的时候,将缓存中最近最少使用(即最长时间没有被使用过)的数据清除,为新数据开辟出空间。

LRU-K 是 LRU 算法的变种,K 代表最近使用的次数,LRU 可以认为是 LRU-1。不同于 LRU 算法的是,LRU-K算法需要维护两套队列(历史访问队列,缓存队列)。当历史访问队列中的数据被命中 K 次后,数据才会移动至缓存队列中。

例如:假设所有队列长度为 5,初始内存中没有数据。使用 LRU-2 算法,数据访问顺序为:9,5,6,7,8,3,8,9,5,9,8,3,4,7,5,6。则历史访问队列和缓存队列的变化如下表所示:

访问元素 历史访问队列 缓存队列

9,5,6,7,8 9,5,6,7,8 空

3 5,6,7,8,3 空

8 5,6,7,3 8

9 5,6,7,3,9 8

5 6,7,3,9 8,5

9 6,7,3 8,5,9

8 6,7,3 5,9,8

3 6,7 5,9,8,3

4 6,7,4 5,9,8,3

7 6,4 5,9,8,3,7

5 6,4 9,8,3,7,5

6 4 8,3,7,5,6

你的任务就是实现这种 LRU-K 缓存机制。

输入格式:

输入第一行给出 3 个正整数:K(1<K≤5)、N (≤10^4 ) 和 M (≤10 ^5),分别为规定的缓存命中次数、队列的大小(假设历史访问队列和缓存队列的大小一致)和被调用的数据的数量。随后一行给出 M 个被调用的数据的编号。编号为区间 [1,2×10 ^4] 内的一个整数。一行中的数字以空格分隔。

输出格式:

在第一行中输出历史访问队列中数据的编号。第二行输出缓存队列中数据的编号。顺序为队头至队尾。数据间以 1 个空格分隔,行首尾不得有多余空格。如果队列为空则输出 - 表示空行。

输入样例 1:

2 5 17

9 5 6 7 8 3 8 9 5 9 8 3 4 7 5 6 9

输出样例 1:

4 9

8 3 7 5 6

输入样例 2:

3 5 10

9 5 6 7 8 3 8 9 5 9

输出样例 2:

7 3 8 5 9

-

代码长度限制

16 KB

Java (javac)

时间限制

900 ms

内存限制

256 MB

其他编译器

时间限制

200 ms

内存限制

64 MB
 

#include<iostream>
#include<vector>
using namespace std;

int main() {
    int K, N, M;
    cin >> K >> N >> M;
    vector<int>p1, p2;
    int t;
    int mz[20005] = { 0 };
    for (int i = 0; i < M; i++) {
        cin >> t; int flag = 0;
        for (auto iter = p2.begin(); iter != p2.end();)
            if (*iter == t) {
                p2.erase(iter);
                flag = 1; break;
            }
            else
                iter++;
        if (flag) { p2.push_back(t); continue; }
        for (auto iter = p1.begin(); iter != p1.end();)
            if (*iter == t)
                p1.erase(iter);
            else
                iter++;
        p1.push_back(t);
        mz[t]++;
        if (mz[t] == K) {
            for (auto iter = p1.begin(); iter != p1.end();)
                if (*iter == t)
                    p1.erase(iter);
                else
                    iter++;
            p2.push_back(t);
            if (int(p2.size()) > N) {
                mz[p2[0]] = 0;
                p2.erase(p2.begin());
            }
        }
        else {
            if (int(p1.size()) > N) {
                mz[p1[0]] = 0;
                p1.erase(p1.begin());
            }
        }
    }
    for (size_t i = 0; i < p1.size(); i++)
        if (i == 0) cout << p1[i];
        else
            cout << " " << p1[i];
    if (p1.size() == 0) cout << '-';
    cout << endl;

    for (size_t i = 0; i < p2.size(); i++)
        if (i == 0) cout << p2[i];
        else
            cout << " " << p2[i];
    if (p2.size() == 0) cout << '-';
    cout << endl;
}

15分

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值