XY1034页面置换
难度:黄金 时间限制:3秒 占用内存:64M
题目描述
FIFO (First-In, First-Out) 是一种页面置换算法。在 FIFO 置换算法中,当系统需要置换页面时,它会将最先加载到内存的页面置换出去。这种方法的做法是,将所有被加载到内存的页面存储在一个队列中,当需要置换页面时,就将队列的第一个页面置换出去。
小码哥想考察一下小码弟对页面置换算法的掌握程度,于是给小码弟提供了一个页面访问序列 p1,p2,…,pn,其中 pi 表示第 i 个被访问的页面编号。小码哥希望小码弟模拟FIFO的页面置换过程,并输出总共的页面置换次数。
显然,操作系统课不及格的小码弟并不清楚该怎么做,于是找到了你来帮忙。
格式
输入格式:第一行输入两个整数 n,m(1≤m≤n≤106),分别表示访问次数和内存中能保存的页面个数(即FIFO中的队列容量)。接下来一行中输入 n 个整数 p1,p2,…,pn(1≤pi≤109),表示访问的页面编号。
输出格式:在一行中输出一个整数,表示页面置换次数。
样例 1
输入:
20 3 7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1输出:
12相关知识点:队列
题解(未ac但在os练习题里面基本ac)
/*
XY1034·页面置换
*/
/*
本题考察的是os的FIFO页面置换算法。
FIFO页面算法:先进先出,每次置换的都是最先进去。
考察的是页面的置换次数,所以不用考察缺页中断次数(缺页中断次数=页面置换次数+内存中能保存的页面个数)
需要解决的问题?
1、栈使用的考察,入队出队
2、就是对于队中已存在的数字不进行入队操作(如何获取当前队列的所有元素)
算法逻辑
1、遍历到一个元素,先查出当前队列的所有元素
2、新元素?
a、先查 pageQueue.size() < m
b、true 直接入队
c、false 弹出队头元素 元素入队
d、页面次数 count++
3、已有元素
直接跳过访问下一个元素 不做任何操作
输入&输出
输入:20 3
7 0 1 2 0 3 0 4 2 3 0 3 2 1 2 0 1 7 0 1
输出:12
*/
#include<iostream>
#include<queue>
using namespace std;
// 遍历队列并判断是否为新元素
bool isNew(queue<int> qu, int x) {
queue<int> tempQu = qu; // 直接另起一个临时的队列用于访问队列内的元素
while (!tempQu.empty()) {
if (x == tempQu.front()) return false; // 已有元素
tempQu.pop();
}
return true;
}
int main() {
int n, m, a; // 访问次数和内存中能保存的页面个数 当前访问的页面
cin >> n;
vector<int> pages(n);
cin >> m;
for (int i = 0; i < n; i++) {
cin >> a;
pages[i] = a;
}
queue<int> pageQueue;
int count = 0; // 页面置换次数
for (int i = 0; i < n; i++) {
if (i <= m - 1) {
pageQueue.push(pages[i]); // 前m个元素进内存
continue; // 防止下面判断元素访问到最开始入队的第三个元素
}
if (isNew(pageQueue, pages[i])) { // 新元素
if (pageQueue.size() < m) pageQueue.push(pages[i]);
else if(pageQueue.size() == m) { // 内存已满
pageQueue.pop(); // FIFO弹出最先访问的元素
pageQueue.push(pages[i]);
}
++count;
} // 已有元素不做任何操作
/*
else
continue;
*/
}
cout << count << endl;
return 0;
}
tips:
并没有通过,很大部分报的是超时,也有4个错误的例子,但因为码蹄集看不到运行的错误例子,所有不知道如何 debug,目前觉得逻辑没有错误,且找了一些关于 FIFO 的例子运行,得出的结果全是正确,所以不知道问题究竟出现在何处(;´༎ຶД༎ຶ`)
希望大佬能够指点!这对我将有很大的帮助,谢谢~