题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1206
题意:
内存大小为n(外存无限大),共有m次访问,每一次访问的信息编号为p。
对于每一条信息,不在内存中,就在外存中。
内存和外存的访问速度不同。为了提高整体的访问速度,有这样一种内存管理的算法:
(1)如果p在内存中,直接访问,算法结束。否则转步骤(2)。
(2)如果内存有剩余空间,则将p由外存转移到内存中来,算法结束。否则转步骤(3)。
(3)选出内存中访问次数最少的一条信息(访问次数相同选进入内存时间早的),用p将它替换掉,算法结束。
访问次数是指:某条信息从进入内存的那一刻开始一直到现在的访问次数。(如果之前进入过内存,然后又被替换掉了,那么之前的访问次数不算)
问你在内存中直接访问到p的次数。(即执行步骤(1)的次数)
题解:
模拟。
用STL中map和set神器~~~
map映射:p的编号idx -> (p的访问次数cnt, p进入内存的时间tim)
set:(idx, cnt, tim) 排序优先级:先cnt,后tim。(均取小)
map用来查询p是否在内存中,以及有关p的信息(以便在set中定位到相应元素)
set用来作优先队列(可任意插入和删除元素),队首为内存中访问次数最少(或进入内存最早)的一条信息。
map和set分别保证了在log(N)时间内的查找和删除(替换)信息。
总复杂度为O(m * log(n))。
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <map> 5 #include <set> 6 7 using namespace std; 8 9 struct Pro 10 { 11 int idx; 12 int cnt; 13 int tim; 14 Pro(int _idx,int _cnt,int _tim) 15 { 16 idx=_idx; 17 cnt=_cnt; 18 tim=_tim; 19 } 20 Pro(){} 21 friend bool operator < (const Pro &a,const Pro &b) 22 { 23 return a.cnt!=b.cnt?a.cnt<b.cnt:a.tim<b.tim; 24 } 25 }; 26 27 int n,m,p; 28 int ans=0; 29 map<int,pair<int,int> > mp; 30 set<Pro> st; 31 32 int main() 33 { 34 cin>>n>>m; 35 for(int i=0;i<m;i++) 36 { 37 cin>>p; 38 map<int,pair<int,int> >::iterator it_mp=mp.find(p); 39 if(it_mp!=mp.end()) 40 { 41 int cnt=(it_mp->second).first; 42 int tim=(it_mp->second).second; 43 st.erase(Pro(p,cnt,tim)); 44 st.insert(Pro(p,cnt+1,tim)); 45 mp[p]=pair<int,int>(cnt+1,tim); 46 ans++; 47 } 48 else if(mp.size()<n) 49 { 50 mp.insert(pair<int,pair<int,int> >(p,pair<int,int>(1,i))); 51 st.insert(Pro(p,1,i)); 52 } 53 else 54 { 55 set<Pro>::iterator it_st=st.begin(); 56 int idx=it_st->idx; 57 int cnt=it_st->cnt; 58 int tim=it_st->tim; 59 mp.erase(idx); 60 st.erase(it_st); 61 mp.insert(pair<int,pair<int,int> >(p,pair<int,int>(1,i))); 62 st.insert(Pro(p,1,i)); 63 } 64 } 65 cout<<ans<<endl; 66 }