1. 程式人生 > 其它 >【ybtoj】【堆的應用】記憶體管理

【ybtoj】【堆的應用】記憶體管理

題意



題解

容易想到:開兩個佇列分別維護空閒記憶體塊序列的編號\((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;
}