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;
}
posted @ 2022-02-18 11:06  l_x_y  阅读(36)  评论(0编辑  收藏  举报