题目:cache的大小为K,表示有K个空间储存item,一开始是空的。当CPU在内存中需要item x时,
如果x在cache里,就可以直接得到它。
如果不在,
先判断cache有没有装满,
如果没装满,将会把x放入cache中。
如果放满了,找出cache中最近最少使用的元素y,然后把y替换成x。
输入有多组数据,对于每组数据。
给定两个整数N和K,N代表内存需要的item数,K表示cache的大小。
第二行包含N个数。
输出,当cache中有该item,输出字符1,没有,输出0(代表缺页)
例子:
7 3
1 2 1 3 4 1 2
0010010
演示:
1 2 1 3 4 1 2
1(LRU) 1 1 2 2 1 3 4
2 2 1 1 3 4 1
3 3 4 1 2
输出 0 0 1 0 0 1 0
做法:
因为只涉及到查询,删除,插入,可用双向链表高效实现,如果用数组,则有大量的移动,耗时。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
const int MAXN=10000;
//双向链表,无头结点
//链表的数组实现
struct QuickList{
int RR[MAXN]; //连接后继 RR[1]=2,RR[2]=4,RR[4]=6
int LL[MAXN];//连接前驱 LL[6]=4,LL[4]=2,LL[2]=1
int front;//头指针
int back;//尾指针
int Len;//链表长度
//初始化
QuickList(){
memset(RR,0,sizeof(RR));
memset(LL,0,sizeof(LL));
front=0;
back=0;
Len=0;
}
void push_back(int a){
if(Len==0){
RR[a]=a;
LL[a]=a;
front=a;
back=a;
}
else{
LL[a]=back;
RR[back]=a;
back=a;
}
Len++;
}
void push_front(int a){
if(Len==0){
RR[a]=a;
LL[a]=a;
front=a;
back=a;
}
else{
LL[front]=a;
RR[a]=front;
front=a;
}
Len++;
}
int pop_back(){
if(Len>0){
int temp=back;
back=LL[back];
RR[temp]=0;
LL[temp]=0;
Len--;
return temp;
}
}
int pop_front(){
if(Len>0){
int temp=front;
front=RR[front];
LL[temp]=0;
RR[temp]=0;
Len--;
return temp;
}
}
void deleteNum(int num){
int temp=RR[num];
RR[num]=0;
RR[LL[num]]=temp;
int temp1=LL[num];
LL[num]=0;
LL[temp]=temp1;
}
bool isExist(int num){
if(RR[num]!=0){
return true;
}
else
return false;
}
};
int main()
{
int n,k;
while (~scanf("%d %d", &n, &k))
{
QuickList list;
for(int i=0;i<n;i++){
int temp;
scanf("%d",&temp);
if(list.isExist(temp)){
printf("1");
list.deleteNum(temp);
list.push_back(temp);
}
else{
printf("0");
if(list.Len>=k){
list.pop_front();
list.push_back(temp);
}
else{
list.push_back(temp);
}
}
}
printf("\n");
}
return 0;
}