• 湘大OJ第1484题 Allocation of Memory


      湘大第1484题,Allocation of Memory题目链接)。

    Allocation of Memory

    Description

      科技发展的速度往往会超过最大胆的想象,盖茨先生很快就为自己的短视付出了代价。他开发的操作系统在内存管理上有重大局限,很快便不再适应个人计算机的飞速发展,所以他不得不请天才的你帮忙改写系统的内存管理模块。

      系统里可以有若干个进程在同时运行,假设系统的总内存大小为M字节,从前到后依次编号为1至M。一开始的时候所有的内存都是可用的。如果在某个时刻某个进程需要使用k字节的内存,它就会向操作系统发出申请,系统会从前到后寻找连续的一段k字节的可用内存,将其分配给该进程。如果同时有多段空间满足要求,会返回最靠前的一段。如果某进程终止,则它所申请的内存重新变为可用。

      可以发现,经过较长时间的运行之后,可能某个新的内存申请再也无法满足,而实际上系统里可能还有足够的可用空间,只是这些空间都成了碎片状。此时你的程序应该自动调用碎片整理过程,把所有当前被占用的空间都移动到内存空间的前部,并保持原来的顺序不变。这样在内存空间的后部可能就空余出了足够多的空间,然后系统继续调用之前的算法来分配内存。如果这样还没有足够的空间,则此次内存申请就失败了。

      你的程序应该对每次内存申请,输出一个地址,表示申请到的内存段的第一个字节的位置。如果申请失败,输出-1。

    Input

      输入的第一行包含一个整数T (T ≤ 15),表示共有T组数据。接下来每组数据的第一行有两个数M, N(1 ≤ M, N ≤ 500),分别表示总内存容量和指令的数目。然后有N行,每行一条指令,指令有两种格式:
    1) New process_id size 表示编号为process_id的进程申请了一块大小为size的内存
    2) Quit process_id 表示编号为process_id的进程退出了,此处的process_id一定在以前出现过,但不保证其一定拥有内存空间

      在每组数据里任意两个进程的编号都不相同,编号为不超过10000的正整数,每次申请的内存大小为一个不超过M的正整数。一个进程可能多次申请内存,但是当进程退出后就不可能再申请内存了。

    Output

      对每组数据,输出一行“Case X:”作为开头,此处X为从1开始的编号。注意首字母C为大写,在“Case”和编号X之间有一个空格,在编号X后面有一个冒号。然后对每个New指令输出一行,表示申请到的内存的第一个字节的位置。如果申请失败,输出-1。

    Sample Input

    2
    10 7
    New 1 3
    New 2 2
    New 1 2
    New 3 2
    Quit 1
    New 4 5
    New 4 5
    5 5
    New 1 5
    New 2 5
    Quit 1
    New 3 5
    Quit 2

    Sample Output

    Case 1:
    1
    4
    6
    8
    5
    -1
    Case 2:
    1
    -1
    1

    Hint

    对于第一组样例,在一号进程退出后内存空间的情况如下图所示:

             2 2       3 3   

    此时找不到连续的5个空位,故开始碎片整理,整理结束以后的情况如下图:

    2 2 3 3                  

    则可以从第5个位置分配新的内存给4号进程:

    2 2 3 3 4 4 4 4 4   

    Source

    “开启时代杯”湘潭市第二届大学生程序设计大赛 (Internet)

      解题思路直接暴力模拟。收到Quit信号,即清空内存为0。否则,察看如果有空间,若有,直接使用,赋值为pid,输出内存地址;否则,碎片整理,再看是否有空间,若有,直接使用,赋值为pid,输出内存地址;若无,输出-1。

      C语言源代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    
    #define MAX_MEMORY 510
    
    typedef int COUNT;
    
    int memory[MAX_MEMORY];
    int maxMemory;
    
    bool canAlloc( int start, int apply )
    {
        COUNT i;
        for ( i = 0 ; i < apply ; i ++ )
        {
            if ( start + i > maxMemory )
                return false;
            if ( memory[start+i] != 0 )
                return false;
        }
        return true;
    }
    
    void defrag(void)
    {
        COUNT i, j;
        for ( i = 1 ; i <= maxMemory ; i ++ )
        {
            if ( memory[i] == 0 )
            {
                for ( j = i + 1 ; j <= maxMemory ; j ++ )
                {
                    if ( memory[j] != 0 )
                    {
                        memory[i] = memory[j];
                        memory[j] = 0;
                        break;
                    }
                }
            }
        }
    }
    
    int alloc( int pid, int apply )
    {
        COUNT i, j;
        for ( i = 1 ; i <= maxMemory ; i ++ )
        {
            if ( memory[i] == 0 )
            {
                if ( canAlloc(i, apply) )
                {
                    for ( j = 0 ; j < apply ; j ++ )
                        memory[i+j] = pid;
                    return i;
                }
            }
        }
        defrag();
        for ( i = 1 ; i <= maxMemory ; i ++ )
        {
            if ( memory[i] == 0 )
            {
                if ( canAlloc(i, apply) )
                {
                    for ( j = 0 ; j < apply ; j ++ )
                        memory[i+j] = pid;
                    return i;
                }
            }
        }
        return -1;
    }
    
    void killprocess( int pid )
    {
        COUNT i;
        for ( i = 1; i <= maxMemory ; i ++ )
        {
            if ( memory[i] == pid )
                memory[i] = 0;
        }
    }
    
    int main (void)
    {
        int testcases;
        COUNT i, j;
        char cmd[12];
        int pid, apply;
        int instructions;
        scanf( "%d", &testcases );
        for ( i = 1 ; i <= testcases ; i ++ )
        {
            scanf( "%d%d", &maxMemory, &instructions );
            memset( memory, 0, sizeof(memory) );
            printf( "Case %d:\n", i );
            for ( j = 0 ; j < instructions ; j ++ )
            {
                scanf( "%s", cmd );
                if ( !strcmp( cmd, "New" ) )
                {
                    scanf( "%d%d", &pid, &apply );
                    printf( "%d\n", alloc( pid, apply ) );
                }
                else
                {
                    scanf( "%d", &pid );
                    killprocess( pid );
                }
            }
        }
        return EXIT_SUCCESS;
    }
  • 相关阅读:
    51nod 1565模糊搜索(FFT)
    51nod 1851俄罗斯方块(trick)
    可持久化线段树(主席树)模板
    BZOJ2191:Splite
    BZOJ4197:[NOI2015]寿司晚宴
    BZOJ3198:[SDOI2013]SPRING
    BZOJ1500:[NOI2005]维修数列
    BZOJ3527:[ZJOI]力
    BZOJ3160:万径人踪灭
    CODE[VS]1372:DNA
  • 原文地址:https://www.cnblogs.com/yejianfei/p/2592786.html
Copyright © 2020-2023  润新知