題目連結: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 }