Problem 1893 内存管理
Accept: 147 Submit: 474
在为进程动态分配内存时,操作系统必须对其进行管理。一种管理内存的方式是,维护一张记录内存使用情况的表来模拟内存的存储情况,其任一表项可能是以下两种情况之一:一个已分配给进程的内存区或者一个空闲的内存区。表中每一个表项含有以下内容:空闲区或已使用内存区的指示标志、内存大小、指向下一表项的指针。
一个表项一般有一个前驱表项和一个后继表项(除非这个表项是内存的最底端或最顶端),已使用区表项的前驱表项和后继表项可能是已使用区表项也可能是空闲区表项,而空闲区表项的前驱表项和后继表项只可能是已使用区表项,因为如果两个空闲区表项如果互为相邻的表项,我们就可以将它们合并为一个空闲区表项,内存大小为两个空闲区表项之和。
当系统创建一个新的进程时,有很多种方法可以用来为新创建的进程分配内存,在这里我们假设已知新进程要占用的内存大小,并只可能给进程分配连续的内存空间。在本题中,我们采用最佳适配算法来分配内存。最佳适配算法搜索整个表,找出够用的最小的空闲区(如有多个,取表中最前的),并将新进程分配在空闲区的顶部,如有剩余内存仍作为空闲区表项,并且为新已使用区表项的下一表项。
当系统结束一个进程时,在整个表中找到相应的已使用区表项并将其变为空闲区表项。
你的任务是编写一个程序,来实现这样一个内存管理的过程。在本题中,初始时内存表只有一个内存空闲区表项,且内存大小为100个单位大小。
输入数据第一行为一整数T,表示有T组输入数据。
每组数据每行是一个系统命令,包括“Create”,“Delete”,“Print”,“End”,每条命令后面的参数如下:
Create:两个整数i和size,i表示新进程的进程号,i>0,size表示新进程需占用的内存大小,size>0,输入保证新进程的进程号与已存在的进程号不同。
Delete:一个整数i,i>0,表示要结束的进程号。
Print:无参数。
End:无参数,不做任何处理,表示系统终止命令。
注意:输入保证出现的表项个数不超过100个。
对于Create命令,如果成功创建新进程,输出一行“Create process i of size s successfully!”,其中i为新进程的进程号,s为新进程占用的内存大小;如果无足够大小的内存空闲区,输出一行“No enough memory!”。
对于Delete命令,如果成功结束进程,输出一行“Delete process i of size s successfully!”,其中i为结束进程的进程号,s为该进程占用的内存大小;如果内存中无该进程,输出一行“No such process!”。
对于Print命令,将内存表从表头开始按顺序输出,每行输出一个表项,进程表项格式为“P 进程号 内存大小”,空闲区表项格式为“H 内存大小”。
对于End命令,不做任何处理,终止程序。
Accept: 147 Submit: 474
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
Input
Output
Sample Input
2Create 1 30Create 2 20Create 3 30PrintCreate 4 100Delete 4Delete 2PrintDelete 3PrintEndCreate 1 100PrintEnd
Sample Output
Create process 1 of size 30 successfully!Create process 2 of size 20 successfully!Create process 3 of size 30 successfully!P 1 30P 2 20P 3 30H 20No enough memory!No such process!Delete process 2 of size 20 successfully!P 1 30H 20P 3 30H 20Delete process 3 of size 30 successfully!P 1 30H 70Create process 1 of size 100 successfully!P 1 100
Source
福州大学第七届程序设计竞赛
题意大家应该看得懂~
做法:其实说难也难,因为很麻烦,说简单也简单,就是分步做。
首先Creat操作,注意点是若有几个相同大小的空间,取最前面的那一个,还有就是除非这一块内存有剩,不然,不然不能另开一个空闲区~
接着Delete操作,注意点是会有连锁效应,我举个例子,1代表已占用内存,0代表未占用内存,那么10101的时候,若删掉最中间的1,那么出现2和3合并,合并完后还能合并!
然后是Print操作和End操作,这两个简单,我是编码的时候临时想。。。
AC代码:
#include<stdio.h>
#include<string.h>
struct memory{
int mark;
int num;
int space;
memory *next;
};
int main() {
int T;
scanf("%d", &T);
while(T--) {
memory *m = new memory;
m->mark = 0;
m->num = -1;
m->space = 100;
m->next = NULL;
char str[25];
while(scanf("%s", str) != EOF) {
if(!strcmp(str, "Create")) {
int n1, big;
int flag1 = 0;
scanf("%d %d", &n1, &big);
memory *p1 = m;
memory *Min = new memory;
Min->space = 0;
while(p1 != NULL) {
if(p1->space > Min->space)
Min = p1;
p1 = p1->next;
}
p1 = m;
while(p1 != NULL) {
if(p1->mark == 0 && p1->space >= big && p1->num != n1) {
if(p1->space < Min->space) {
Min = p1;
flag1 = 1;
}
else if(p1->space <= Min->space && p1->next == NULL) {
Min = p1;
flag1 = 1;
}
}
p1 = p1->next;
}
if(flag1) {
Min->mark = 1;
Min->num = n1;
if((Min->space - big) > 0) {
memory *t = new memory;
t->mark = 0;
t->num = -1;
t->space = Min->space - big;
t->next = Min->next;
Min->next = t;
}
Min->space = big;
printf("Create process %d of size %d successfully!\n", n1, big);
}
else
printf("No enough memory!\n");
}
else if(!strcmp(str, "Print")) {
memory *p2 = m;
while(p2 != NULL) {
if(p2->mark == 1)
printf("P %d %d\n", p2->num, p2->space);
else
printf("H %d\n", p2->space);
p2 = p2->next;
}
}
else if(!strcmp(str, "Delete")) {
int n2;
int flag2 = 0;
scanf("%d", &n2);
memory *p3 = m;
while(p3 != NULL) {
if(p3->num == n2) {
printf("Delete process %d of size %d successfully!\n", p3->num, p3->space);
flag2 = 1;
p3->mark = 0;
p3->num = -1;
memory *p4 = m;
while(p4 != NULL) {
while(p4->mark == 0 && p4->next != NULL && p4->next->mark == 0) {
p4->space = p4->space + p4->next->space;
p4->next = p4->next->next;
}
p4 = p4->next;
}
}
p3 = p3->next;
}
if(!flag2)
printf("No such process!\n");
}
else if(!strcmp(str, "End")) {
delete m;
break;
}
}
}
return 0;
}