题意
题解
容易想到:开两个队列分别维护空闲内存块序列的编号((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
",u);
}
//询问内存块
else
{
y=read();
if(ocu[y]) printf("+
");
else printf("-
");
if(ocu[y])//这个判断卡了我好久...只有已经被占用再访问才更新时间
ocu[y]++,q2.push(mp(y,x));//更新时间,放入q2
}
}
return 0;
}