Description
Little Hi is studying on memory allocating algorithms this summer. He starts his experiments with a very simple algorithm. By this algorithm memory is considered as a sequence of M consecutive storage units, numbered from 0 to M-1.
Whenever a piece of data is written to the memory the algorithm finds from 0 to M-1 the first segment of consecutive empty units which is large enough and save the data there. For example if the data size is 2 after saving it the memory look as below. Units are marked as 1 because they contain the 1st data we write.
If we continue to write two pieces of data of size 3 and 2 the memory looks like below. Units 2-4 contain the 2nd data and Units 5 and 6 contain the 3rd data.
If there is not enough consecutive empty units for the coming data the algorithm will keep removing the earliest data until the coming data can be saved. Assume the memory if full after we write the 8th data:
And we need to write the 9th data of size 4. The algorithm removes the 1st data:
There is still not enough consecutive empty units so the 2nd data is also removed. Then the 9th data is saved at Units 0-3:
Remember if there are multiple possible segments to save the coming data the algorithm always choose the segment which is started at the unit of the smallest number.
After writing N data of different sizes Little Hi wants to know what the memory looks like.
Input
Line 1: N and M, the number of data and the size of the memory.
Line 2: N integers, K1, K2 …, KN. Ki is the size of the ith data.
For 60% of the data 1≤N≤200,10≤M≤100,1≤Ki≤5
For 100% of the data 1≤N≤2,000,10≤M≤109,1≤Ki≤M
Output
For each data which is still in the memory at last output one line of two integers id and s: the number of the data and its starting position in the memory. Output them in increasing order of id.
Sample Hint
The memory looks after saving each data:
1 1 1 1 1 0 0 0 0 0
1 1 1 1 1 2 2 0 0 0
1 1 1 1 1 2 2 3 3 0
4 4 0 0 0 2 2 3 3 0
4 4 5 5 5 5 0 3 3 0
4 4 5 5 5 5 6 6 6 6
- Sample Input
-
6 10 5 2 2 2 4 4
- Sample Output
-
4 0 5 2 6 6
Solution:
1 #include <cstdio> 2 #include <deque> 3 #include <algorithm> 4 using namespace std; 5 6 7 struct chunk { 8 int v, s, e; 9 }; 10 11 int main() { 12 int n, m; 13 scanf("%d%d", &n, &m); 14 deque<chunk> que; 15 int c; 16 bool f = true; 17 for (int k = 1; k <= n; ++k) { 18 if(f) scanf("%d", &c); 19 if (que.empty()) { 20 que.push_back({ k, 0, c - 1 }); 21 } 22 else { 23 bool flag = false; 24 int minK = n + 1; 25 int idx = -1; 26 for (int i = 0; i < que.size(); ++i) { 27 if (minK > que[i].v) { 28 minK = que[i].v; 29 idx = i; 30 } 31 if (i == 0) { 32 if (c - 1 < que[i].s) { 33 que.push_front({ k, 0, c - 1 }); 34 flag = true; 35 break; 36 } 37 } 38 if (i == que.size() - 1) { 39 if (que[i].e + c < m) { 40 que.push_back({ k, que[i].e+1, que[i].e + c }); 41 flag = true; 42 break; 43 } 44 45 } 46 47 else { 48 if (que[i + 1].s - que[i].e - 1 >= c) { 49 que.insert(que.begin() + i + 1, { k, que[i].e + 1, que[i].e + c }); 50 flag = true; 51 break; 52 } 53 } 54 } 55 56 if (!flag) { 57 que.erase(que.begin() + idx); 58 k--; 59 f = false; 60 } 61 else { 62 f = true; 63 } 64 } 65 } 66 67 sort(que.begin(), que.end(), [](const chunk &ch1, const chunk &ch2) { 68 return ch1.v < ch2.v; 69 }); 70 for (int k = 0; k < que.size(); ++k) { 71 printf("%d %d\n", que[k].v, que[k].s); 72 } 73 }