Timus 1037. Memory Management

Source: Internet
Author: User
ArticleDirectory
    • Background
    • Problem
    • Input
    • Output
    • Sample
    • Question
    • Solutions
    • Further discussion

Timus 1037. Memory Management requires you to implement a memory manager.

1037. Memory Management

Time Limit: 2.0 second
Memory limit: 16 MB

Background

Don't you know that at school pupils 'Programming contest a new computer language has been developed. we call it d ++. generally speaking it doesn' t matter if you know about it or not. but to run programs written in D ++ we need a new operating system. it shoshould be rather powerful and complex. it shoshould work fast and have a lot of possibilities. but all this shoshould be done in a future.

And now you are... No. you shoshould not devise the name for the operating system. you are to write the first module for this new OS. and of course it's the memory management module. let's discuss how it is expected to work.

Problem

Our operating system is to allocate memory in pieces that we'll call "blocks". The blocks are to be numbered by integers from 1 upN. When operating system needs more memory it makes a request to the memory management module. to process this request the memory management module shocould find free memory block with the least number. you may assume that there are enough blocks to process all requests.

Now we shoshould define the meaning of words "free block ". at the moment of first request to the memory management module all blocks are considered to be free. also a block becomes free when there were no requests to itTMinutes.

You may wonder about a notion "request to allocated blocks". What does it mean, "request to allocated block "? The answer is simple: at any time the memory management module may be requested to access a given block. to process this request the memory management module shocould check if the requested block is really allocated. if it is, the request is considered to be successful and the block remains allocatedTMinutes more. Otherwise the request is failed.

That's all about the algorithms of the memory management block. You are to implement themN= 30 000 andT= 10 minutes.

Input

Each line of input contains a request for memory block allocation or memory block access. Memory Allocation request has a form:

<Time> +

Where <time> is a nonnegative integer number not greater than 65 000. Time is given in seconds. memory block access request has a form:

<Time>. <blockno>

Where <time> meets conditions mentioned above for the memory allocation request and <blockno> is an integer value in range from 1N. There will be no more than 80000 requests.

Output

For each line of input you shoshould print exactly one line with a result of request processing. for memory allocation request you are writing an only integer-a number of allocated blocks. as it was mentioned above you may assume that every request can be satisfied, there will be no moreNSimultaneously allocated blocks. For memory block access request you shoshould print the only character:

    • '+' If request is successful (I. e. Block is really allocated );
    • '-' If request fails (I. e. Block with number given is free, so it can't be accessed ).

Requests are arranged by their times in an increasing order. Requests with equal times shocould be processed as they appear in input.

Sample
Input Output
1 +
1 +
1 +
2. 2
2. 3
3. 30000
601. 1
601. 2
602. 3
602 +
602 +
1202. 2
1
2
3
+
+
-
-
+
-
1
3
-

Problem Author:Alexander klepinin
Problem Source:Ural State University internal Contest October '2000 students session

Question

A newProgramThe design language D ++ was developed for the program design competitions attended by students. However, a new operating system is required to run programs written in the D ++ language. Now you need to write the first module for the new operating system: memory management.

The operating system allocates memory in blocks from 1N. When the operating system requires memory, it sends a request to the memory management module. After receiving the request, the memory management module allocates the "free block" with the smallest number ".

Any allocated "memory block"TIf no access request is received within minutes, it will be released and become a "free block ".

At any time, the operating system can request access to a specified "memory block ". If the "memory block" has not been allocated, the request will fail. Otherwise, the request is successful and the "memory block" is keptTNot released in minutes.

Each input row contains a memory allocation request or memory access request. The memory allocation request is as follows:

<Time> +

Memory access requests are as follows:

<Time>. <blockno>

Here<Time>Is a non-negative integer not greater than 65,000, indicating the request time.<Blockno>Is a 1NIndicates the number of the memory block to be accessed.

Each line of input has a row of output. For memory allocation requests, output the allocated "memory block" number. For memory access requests, if the request is successful, the "+" number is output. Otherwise, the "-" number is output.

Solutions

At the beginning of the program, a priority queue will be established to store allocated "memory blocks. Therefore, a data structure is required to represent the "memory block", as shown below:

StructBlock{Public intId {Get;Private set;}Public intTime {Get;Set;}PublicBlock (IntID,IntTime ):This() {Id = ID; time = Time ;}}

HereIDIndicates the number of the "memory block,TimeIndicates the expiration time of the "memory block" (after this time, the "memory block" will be released ).

Because the "memory block" will first be out of the queue at the early expiration time, it should be "Small priority", rather than the general "large priority ". Therefore, a backward comparator is required, as shown below:

Sealed classTimecomparer:Icomparer<Block> {Public intCompare (BlockX,BlockY ){Return(X. Time = Y. Time )? 0: (X. time <Y. Time )? 1:-1 );}}

Next, a priority queue is created for storing the "free block" number. Because the memory management module will allocate the smallest "free block", a backward "comparator" is also required, as shown below:

Sealed classIdcomparer:Icomparer<Int> {Public intCompare (IntX,IntY ){Return(X = y )? 0: (x <Y )? 1:-1 );}}

Now it's the turn of the main program:

 Using System; Using System. Collections. Generic; Using Skyiv. util; Namespace Skyiv. Ben. timus { // Http://acm.timus.ru/problem.aspx? Space = 1 & num = 1037  Sealed class T1037 { Static void Main (){ Const int T = 10*60, n = 30000; VaR Used = New  Keyedpriorityqueue ( New  Timecomparer ()); VaR Free = New  Priorityqueue < Int > ( New Idcomparer ()); For ( VaR I = 1; I <= N; I ++) free. Push (I ); For ( String S; (S = Console . Readline ())! = Null ;){ VaR Ss = S. Split (); Int ID, time = Int . Parse (ss [0]); For ( Block V; used. Count> 0 & (V = used. Top (). time <= time; used. Pop () free. Push (V. ID ); If (Ss. Length = 2) {used. Push ( New  Block (ID = free. Pop (), time + T )); Console . Writeline (ID );} Else if (Ss. Length = 3 ){ VaR Hited = used. containskey (ID = Int . Parse (ss [2]); If (Hited) used. Update ( New  Block (ID, time + T )); Console . Writeline (hited? "+" : "-" );}}}}}

This sectionCodeIt is very simple. In the main cycle of the main method, read the input by row to obtain the request time (Time =Int. Parse (ss [0])), And then use a loop to release all expired "memory blocks" in the used Queue (Used. Pop ()And add its ID to the free queue (Free. Push (V. ID)).

Then, if the request is to allocate memory (SS. Length = 2In the free queue and add it to the used Queue (Used. Push (NewBlock(ID = free. Pop (), time + T ))), And then output the "memory block" number (Console. Writeline (ID)).

For memory access requests (SS. Length = 3), Check whether the "memory block" to be accessed is in the used Queue (Hited = used. containskey (ID =Int. Parse (ss [2])), If yes, update its expiration time (Used. Update (NewBlock(ID, time + T ))). Finally, the output result (Console. Writeline (hited?"+":"-")).

Now, it's time to store the priority queue of allocated "memory blocks"KeyedpriorityqueuePlaying:

 Class  Keyedpriorityqueue { Dictionary < Int , Int > Keys;Icomparer < Block > Comparer; Block [] Heap; Public int Count { Get ; Private set ;} Public Keyedpriorityqueue ( Icomparer < Block > Comparer ){ This . Keys = New  Dictionary < Int ,Int > (); This . Comparer = (comparer = Null )? Comparer < Block >. Default: comparer; This . Heap = New  Block [16];} Public bool Containskey ( Int ID ){ Return Keys. containskey (ID );} Public void Update (Block V ){ If (! Containskey (V. ID )) Throw new  Argumentoutofrangeexception ( "V" , V, "This key is not found when priority queue is updated" ); VaR CMP = comparer. Compare (v, heap [Keys [v. ID]); heap [Keys [v. ID]. Time = V. time; If (CMP <0) siftdown (Keys [v. ID]); Else if (CMP> 0) siftup (Keys [v. ID]);} Public void Push ( Block V ){If (Count> = heap. length) Array . Resize ( Ref Heap, count * 2); heap [Keys [v. ID] = count ++] = V; siftup (Keys [v. ID]);} Public  Block Pop (){ VaR V = Top (); keys. Remove (V. ID); heap [0] = heap [-- count]; If (Count> 0) siftdown (Keys [heap [0]. ID] = 0 ); Return V ;} Public  Block Top (){ If (Count> 0)Return Heap [0]; Throw new  Invalidoperationexception ( "Priority queue is blank" );} Void Siftup ( Int N ){ VaR V = heap [N]; For ( VaR N2 = n/2; n> 0 & comparer. compare (v, heap [n2])> 0; n = n2, n2/= 2) Heap [Keys [heap [n2]. id] = N] = heap [n2]; heap [Keys [v. id] = N] = V ;} Void Siftdown ( Int N ){VaR V = heap [N]; For ( VaR N2 = N * 2; N2 <count; n = n2, N2 * = 2 ){ If (N2 + 1 <count & comparer. Compare (heap [n2 + 1], heap [n2])> 0) N2 ++; If (Comparer. Compare (v, heap [n2])> = 0) Break ; Heap [Keys [heap [n2]. ID] = N] = heap [n2];} heap [Keys [v. ID] = N] = V ;}}

As shown above,KeyedpriorityqueueClass and what I implemented in the previous article "using C # to implement priority queue"Priorityqueue<T>Classes are very similar. The twoAlgorithmIn the same way, "Heap" is used to implement priority queues.

KeyedpriorityqueueUse a dictionary (Dictionary<Int,Int> KeysTo store the ID of the "memory block" and Its index in the heap, so as to determine whether the given "memory block" is in the queue (BoolContainskey (IntID)And update the expiration time (Update (BlockV)).

Other methods,Push,Pop,Top,Siftup,SiftdownIn addition to processing the dictionary keysPriorityqueue<T>The class is the same.

Further discussion

Used in this programKeyedpriorityqueueTo store allocated "memory blocks", usePriorityqueue<T>To store unallocated "Free blocks ". The algorithms of the two priority queues are the same. You can merge them. This will be discussed in the next article.

This question assumes that the scale of the problem meets the following constraints:

    1. Total number of memory blocksNUp to 30,000
    2. TimeTimeUp to 65,000
    3. The total number of requests cannot exceed 80,000

We only use the first constraint in the program, that is, add all "memory blocks" to the priority queue free of the "free block" storage in the fourth row of the main method:

For(VaRI = 1; I <= N; I ++) free. Push (I );

In fact, this restriction can be easily bypassed. We can modify the priority queue for storing "Free blocks", as shown below:

Sealed classMypriorityqueue{IntId = 1;Priorityqueue<Int> Queue;PublicMypriorityqueue (Icomparer<Int> Comparer) {queue =NewPriorityqueue<Int> (Comparer );}Public voidPush (IntV) {queue. Push (V );}Public intPop (){Return(Queue. Count = 0 )? Id ++: queue. Pop ();}}

ThenPriorityqueue<Int>ReplaceMypriorityqueueAnd deleteN = 30000You can.

Because inMypriorityqueueIn the pop method of the class, once the priority queue is found to be empty, the value of the field ID is returned, and the value of the ID is increased by one. This ID is the number of the smallest "free block" to be allocated.

In this way, our memory management module can ignore the restrictions of the question and continue to work normally when the problem scale exceeds these restrictions.

Returned directory

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.