CF7B Memory Manager 题解
分析
一道大模拟。每次操作分别处理即可。
alloc 实现
从 \(1\) 向 \(m\) 找,如果从这个点开始有长度大于等于 \(n\) 的空间没有被利用过,就将这里的每一个点标记为用过,如果循环完还没有能放的空间,就说明放不下。
if(s=="alloc")
{
scanf("%d",&x);
int c=0,pos=0;
for(i=1;i<=m;i++)
{
j=i;c=0; //j记录i之后循环到点的位置,c记录目前空间的大小
while(!vis[j]&&j<=m) j++,c++; //连续的空间没被用过
if(c>=x) //放得下
{
pos=i;
break;
}
}
if(c>=x) //能放下
{
for(j=pos;j<=pos+x-1;j++) //将新开的内存中每个点都标记成用过
{
vis[j]=true;
}
printf("%d\n",++cnt); //cnt记录当前放入内存的编号
flag[cnt]=true;
a.push_back(make_pair(pos,pos+x-1)); //记录这段内存的头和尾
continue;
}
else //放不下
{
printf("NULL\n");
continue;
}
}
erase 实现
如果要删除的内存编号大于此时最大的编号或者之前释放过,就说明不能释放,否则将这段内存中的每一个点标记成没用过。
if(s=="erase")
{
scanf("%d",&x);
if(x<0||x>inf) //特判编号过小或过大,防止溢出
{
printf("ILLEGAL_ERASE_ARGUMENT\n");
continue;
}
if(!flag[x]) //此时没有占用编号x的内存
{
printf("ILLEGAL_ERASE_ARGUMENT\n");
continue;
}
int s=a[x].first,t=a[x].second;
flag[x]=false; //标记为目前没有编号为x的内存
a[x]=make_pair(-1,-2); //标记头尾
for(i=s;i<=t;i++) //标记区间内的每一个点为未使用
{
vis[i]=false;
}
continue;
}
defragment 实现
按照当前每个内存块的位置从 \(1\) 开始,每个内存块大小不变,重新依次分配空间即可。
if(s=="defragment")
{
mem(vis,0);
j=1;
vector<int>tmp; //记录按当前内存块顺序排的内存块编号
tmp.clear();
for(i=1;i<=m;i++)
{
for(j=1;j<a.size();j++)
{
if(!flag[j]) continue;
if(a[j].first<=i&&a[j].second>=i&&(tmp.empty()||tmp.back()!=j)) //i属于j号内存
{
tmp.push_back(j);
break;
}
}
}
j=1;
for(int ii=0;ii<tmp.size();ii++)
{
i=tmp[ii];
if(!flag[i]) continue;
int s=j;
for(k=a[i].first;k<=a[i].second;k++)
{
vis[j++]=true; //标记新区间内的每个点
}
a[i].first=s;a[i].second=j-1; //重新记录左右端点
}
}
完整代码
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a));
#define elif else if
#define puchar putchar
using namespace std;
typedef pair<int,int> Pair;
const int inf=2139062143;
const int MAXN=107;
int n,m,x,tail,cnt;
string s;
vector<Pair>a;
bool vis[MAXN];
bool flag[MAXN];
int main()
{
scanf("%d%d",&n,&m);
a.push_back(make_pair(0,0));
while(n--)
{
int i,j,k;
cin>>s;
if(s=="alloc")
{
scanf("%d",&x);
int c=0,pos=0;
for(i=1;i<=m;i++)
{
j=i;c=0;
while(!vis[j]&&j<=m) j++,c++;
if(c>=x)
{
pos=i;
break;
}
}
if(c>=x)
{
for(j=pos;j<=pos+x-1;j++)
{
vis[j]=true;
}
printf("%d\n",++cnt);
flag[cnt]=true;
a.push_back(make_pair(pos,pos+x-1));
continue;
}
else
{
printf("NULL\n");
continue;
}
}
if(s=="erase")
{
scanf("%d",&x);
if(x<0||x>inf)
{
printf("ILLEGAL_ERASE_ARGUMENT\n");
continue;
}
if(!flag[x])
{
printf("ILLEGAL_ERASE_ARGUMENT\n");
continue;
}
int s=a[x].first,t=a[x].second;
// cout<<a[x].first<<" "<<a[x].second<<endl;
flag[x]=false;
a[x]=make_pair(-1,-2);
for(i=s;i<=t;i++)
{
vis[i]=false;
}
continue;
}
if(s=="defragment")
{
mem(vis,0);
j=1;
int sum=0;
vector<int>tmp;
tmp.clear();
for(i=1;i<=m;i++)
{
for(j=1;j<a.size();j++)
{
if(!flag[j]) continue;
if(a[j].first<=i&&a[j].second>=i&&(tmp.empty()||tmp.back()!=j))
{
tmp.push_back(j);
break;
}
}
}
j=1;
for(int ii=0;ii<tmp.size();ii++)
{
i=tmp[ii];
if(!flag[i]) continue;
int s=j;
for(k=a[i].first;k<=a[i].second;k++)
{
vis[j++]=true;
}
a[i].first=s;a[i].second=j-1;
}
}
}
return 0;
}