【ybtoj】【堆的應用】記憶體管理
阿新 • • 發佈:2021-09-13
題意
題解
容易想到:開兩個佇列分別維護空閒記憶體塊序列的編號\((q1)\),被佔用的記憶體塊的的編號與過期時間\((q2)\)
同時更新\(ocu\)陣列,記錄程式碼塊是否被佔用
但是我卡在了細節的地方很久:if(ocu[y]) ocu[y]++,q2.push(mp(y,x));
詢問的時候沒有打上判斷就直接\(push\)到\(q2\)裡了,這樣會把本來沒佔用的記憶體塊錯誤地佔用
上程式碼(註釋詳細=w=)
程式碼
#include<bits/stdc++.h> using namespace std; #define ll long long #define pr pair<int,int> #define mp make_pair const int INF = 0x3f3f3f3f,n = 30000; inline ll read() { ll ret=0;char ch=' ',c=getchar(); while(!(c>='0'&&c<='9')) ch=c,c=getchar(); while(c>='0'&&c<='9') ret=(ret<<1)+(ret<<3)+c-'0',c=getchar(); return ch=='-'?-ret:ret; } priority_queue<int,vector<int>,greater<int> > q1;//維護空閒的編號序列 queue<pr>q2;//維護操作時間 int tim[n+1],ocu[n+1]; int main() { for(int i=1;i<=n;i++) q1.push(i); int x,y; while(scanf("%d",&x)!=EOF) { char op[3]; scanf("%s",op); //開始先把q2中所有到時間的記憶體塊取出 while(!q2.empty()) { pr u=q2.front(); if(u.second+600<=x) { q2.pop(),ocu[u.first]--;//佔用-- if(!ocu[u.first]) q1.push(u.first); //如果該記憶體塊空閒則放入q1 } else break; } //佔用記憶體塊 if(op[0]=='+') { int u=q1.top();q1.pop(); //申請一個空記憶體塊,拿出q1 q2.push(mp(u,x));//放入q2,記錄時間 ocu[u]++;//佔用++ printf("%d\n",u); } //詢問記憶體塊 else { y=read(); if(ocu[y]) printf("+\n"); else printf("-\n"); if(ocu[y])//這個判斷卡了我好久...只有已經被佔用再訪問才更新時間 ocu[y]++,q2.push(mp(y,x));//更新時間,放入q2 } } return 0; }