---
# System prepended metadata

title: 北軟107 problemD
tags: [北軟107]

---

# 北軟107 problemD

###### tags: `北軟107`

## 競賽題目：

簡易最適配置法之記憶體管理 (Memory Management---Best fit)程式
說明：在作業系統中，最適配置法之記憶體管理單元能依需求分配夠大而且最接
近需求的閒置空間來放置程序 (Process) 程式。

例如：有 3 個程序(如下左圖)所需佔用的記憶體空間分別為 5、6、8 個單位。
閒置的記憶體空間如下右圖，有 3 個區塊、大小分別為 7、5、9 個單位，一個記
憶體單位大小等同 2 個等號。 

![image alt](https://cdn.discordapp.com/attachments/592247718194184213/595850774425239573/unknown.png)

程序配置前的記憶體空間是空白的 (如上右圖上半部分)，程序配置後的記憶體
空間是顯示程序號碼及數個等號 (如上右圖下半部分)。因採用最適配置法，P1
程序需要 5 個單位所以被配置到 >=5 單位的區塊 2，並用\=\=號填滿整區塊。P2 程
序需要 6 個單位所以被配置到 >=6 單位且最接近 6 個單位的區塊 1，並用\=\=號填
入該區塊，只留下 1 單位空間。P3 程序需要 8 個單位所以被配置到 >=8 單位且最
接近 8 個單位的區塊 3，並用\=\=號填入該區塊，只留下 1 單位空間。 

目標：
1. 請寫一支程式如下圖所示，區塊數<6 和程序數<6，顯示相關訊息 (2 分)。
2. 可輸入記憶體區塊數量及程序數量(2分)。
3. 接著輸入每個記憶體區塊的大小，最後一個區塊輸入後才換行(4 分)。
4. 接著輸入每個程序所需的區塊大小，最後一個程序輸入後才換行(4 分)。 
5. 接著採最適配置法依程序順序將相關資訊顯示出來(13 分)。 

注意：不用處理資料輸入錯誤問題。

![image alt](https://cdn.discordapp.com/attachments/592247718194184213/595851260062728213/unknown.png)

另一例子如下圖：
因採用最適配置法，
P1 程序需要 8個單位所以被配置到 >=8 單位的區塊2，並用\=\=號填滿整區塊。
P2 程序需要 7 個單位，因沒有 >=7 單位的空間，所以未被配置。
P3 程序需要 6個單位所以被配置到 >=6 單位的區塊1，並用\=\=號填滿整區塊。
P4 程序需要 6 個單位，因沒有 >=6 單位的空間，所以未被配置。 

![image alt](https://cdn.discordapp.com/attachments/592247718194184213/595851657128968212/unknown.png)

## 解題想法

由於這題給的記憶體區塊數與程序數非常少，所以這題我們可以直接暴力破解。
開6個迴圈，每個迴圈從0開始，運行條件為變數數值小於記憶體區塊數，且變數數值遞增。

接下來，我們就能夠將變數數值當成該程序選擇哪個記憶體區塊，判斷是否放得進去。
由於我們要求最適配置，所以我們要盡可能的讓記憶體區塊的記憶體剩餘最少。

所以，在我們做上一個步驟時，
我們要設一個變數count來記錄剩餘的記憶體數量，且這個變數的初始值非常大。
再設一個陣列select來記錄第i個程序放置在哪個記憶體區塊。
和一個紀錄整數的List**陣列**group來紀錄在第i個記憶體區塊內有哪些程序。

在六個迴圈的內部程式碼，我們開一個vec來複製紀錄區塊數的陣列，和一個item來複製紀錄程序大小的陣列，和一個put來記錄該程序是否有放進去記憶體內。

接下來開一個迴圈來記錄記憶體的剩餘數量，假設剩餘數量小於count，就將count設為目前剩餘的數量，然後更新陣列select和group。

接下來設計界面(最麻煩的部分)，這邊由於很直觀所以不多做講解。

## 程式碼(C#)

```csharp=
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace problemD
{
    class Program
    {
        static String fixedString(string str)
        {
            return str.PadRight(16, ' ');
        }
        static void printPart1(int n,int[] spaceArray)
        {
            Console.Write("　　　　　█");
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j <= spaceArray[i]; j++)
                {
                    Console.Write("█");
                }
            }
            Console.WriteLine();
        }
        static void printPart2(int n, int[] spaceArray)
        {
            Console.Write("　　　　　");
            for (int i = 0; i < n; i++)
            {
                Console.Write("█");
                Console.Write("".PadRight(spaceArray[i] * 2, ' '));
            }
            Console.Write("█");
            Console.WriteLine();
        }
        static void printPart2(string str,int n, int[] spaceArray)
        {
            Console.Write(str);
            for (int i = 0; i < n; i++)
            {
                Console.Write("█");
                Console.Write("".PadRight(spaceArray[i] * 2, ' '));
            }
            Console.Write("█");
            Console.WriteLine();
        }
        static void printPart2(string str, int n, int[] spaceArray, int[] programming, List<int>[] group)
        {
            Console.Write(str);
            for (int i = 0; i < n; i++)
            {
                Console.Write("█");
                string rst = "";
                for (int j = 0; j < group[i].Count(); j++)
                {
                    int id = group[i][j];
                    if (programming[id] == 0) continue;
                    rst += ("P" + (id + 1)).PadRight(programming[id] * 2, '=');
                }
                rst = rst.PadRight(spaceArray[i]*2, ' ');
                Console.Write(rst);
            }
            Console.Write("█");
            Console.WriteLine();
        }
        static void printPart3(int n, int[] spaceArray)
        {
            Console.Write("　　　　　　");
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < spaceArray[i]; j++)
                {
                    Console.Write((j+1) + "-");
                }
                Console.Write("  ");
            }
            Console.Write("　");
            Console.WriteLine();
        }
        static void Main(string[] args)
        {
            int n, m;
            Console.WriteLine("記憶體管理程式-最適配置法(Best Fit)");
            Console.Write("請輸入記憶體區塊數(<6):");
            n = Convert.ToInt32(Console.ReadLine());
            Console.Write("請輸入程序數(<6):");
            m = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine();
            Console.WriteLine("請輸入各區塊大小(<10)---");
            int[] spaceArray = new int[6];
            int[] programArray = new int[6];
            for (int i = 0; i < 6; spaceArray[i] = 0, i++) ;
            for (int i = 0; i < 6; programArray[i] = 0, i++) ;
            for(int i = 0; i < n; i++)
            {
                Console.Write("區塊" + (i + 1) + ":");
                spaceArray[i] = Convert.ToInt16(Console.ReadKey().KeyChar - '0');
                Console.Write(", ");
            }
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("請輸入各程式所需大小(<10)---");
            for (int i = 0; i < m; i++)
            {
                Console.Write("程序" + (i + 1) + ":");
                programArray[i] = Convert.ToInt16(Console.ReadKey().KeyChar - '0');
                Console.Write(", ");
            }
            int[] select = new int[6];
            List<int>[] group = new List<int>[6];
            for (int i = 0; i < 6; select[i] = 0, i++);
            int count = 100000;
            for (int a = 0; a < n; a++)
            {
                for (int b = 0; b < n; b++)
                {
                    for (int c = 0; c < n; c++)
                    {
                        for (int d = 0; d < n; d++)
                        {
                            for (int e = 0; e < n; e++)
                            {
                                for (int f = 0; f < n; f++)
                                {
                                    int[] vec = new int[6];
                                    int[] item = new int[6];
                                    bool[] put = new bool[6];
                                    for (int i = 0; i < 6; i++)
                                    {
                                        vec[i] = spaceArray[i];
                                    }
                                    for (int i = 0; i < 6; i++)
                                    {
                                        item[i] = programArray[i];
                                    }
                                    if (vec[a] - item[0] >= 0)
                                    {
                                        put[0] = true;
                                        vec[a] -= item[0];
                                    }
                                    if (vec[b] - item[1] >= 0)
                                    {
                                        put[1] = true;
                                        vec[b] -= item[1];
                                    }
                                    if (vec[c] - item[2] >= 0)
                                    {
                                        put[2] = true;
                                        vec[c] -= item[2];
                                    }
                                    if (vec[d] - item[3] >= 0)
                                    {
                                        put[3] = true;
                                        vec[d] -= item[3];
                                    }
                                    if (vec[e] - item[4] >= 0)
                                    {
                                        put[4] = true;
                                        vec[e] -= item[4];
                                    }
                                    if (vec[f] - item[5] >= 0)
                                    {
                                        put[5] = true;
                                        vec[f] -= item[5];
                                    }
                                    bool find = false;
                                    int mn = 0;
                                    for (int i = 0; i < 6 && find == false; i++)
                                    {
                                        mn += vec[i];
                                    }
                                    if (mn < count)
                                    {
                                        select[0] = (put[0] == true ? a : -1);
                                        select[1] = (put[1] == true ? b : -1);
                                        select[2] = (put[2] == true ? c : -1);
                                        select[3] = (put[3] == true ? d : -1);
                                        select[4] = (put[4] == true ? e : -1);
                                        select[5] = (put[5] == true ? f : -1);
                                        for (int i = 0; i < 6; group[i] = new List<int>(), i++) ;
                                        for (int i = 0; i < select.Length; i++)
                                        {
                                            int val = select[i];
                                            if (val == -1) continue;
                                            group[val].Add(i);
                                        }
                                        count = mn;
                                    }                                   
                                }
                            }
                        }
                    }
                }
            }
            Console.WriteLine();
            Console.WriteLine();
            for (int i = 0; i <= m; i++)
            {
                if(i == 0)
                {
                    Console.WriteLine("程式編號　　　　所需大小　　　　區塊編號　　　　區塊大小　　　　剩餘空間");
                    continue;
                }
                Console.Write(fixedString(i.ToString()));
                Console.Write(fixedString(programArray[i - 1].ToString()));
                int sel = select[i - 1];
                if (sel != -1)
                {
                    Console.Write(fixedString((select[i - 1] + 1).ToString()));
                    Console.Write(fixedString(spaceArray[select[i - 1]].ToString()));
                    Console.Write(fixedString((spaceArray[select[i - 1]] - programArray[i - 1]).ToString()));
                }
                else
                {
                    Console.Write("未分配記憶體區塊");
                    Console.Write(fixedString(""));
                    Console.Write(fixedString(""));
                }
                Console.WriteLine();
            }
            Console.WriteLine();
            printPart1(n, spaceArray);
            printPart2(n, spaceArray);
            printPart2("配置程序前", n, spaceArray);
            printPart2(n, spaceArray);
            printPart1(n, spaceArray);
            printPart3(n, spaceArray);
            printPart1(n, spaceArray);
            printPart2(n, spaceArray);
            printPart2("程序配置後", n, spaceArray,programArray,group);
            printPart2(n, spaceArray);
            printPart1(n, spaceArray);
        }
    }
}
```