磁盘驱动调度问题-贪心

题目:

输入一个请求序列:98,183,37,122,14,124,65,67

假设磁头一开始的位置start处于c(c不在序列中的任何位置),例如c=53

如果采用最短寻道优先SSTF,输出序列的调度顺序和磁头移动总数

 

思路:

首先SSTF属于操作系统的知识,表示每一次都找离当前位置最近的一个磁道去处理,根据这个定义就很自然地想到贪心

我把所有的序列按递增排序,将start位置也排进去,这样离当前位置最近的磁道就是左边下标最靠近他的元素或者右边下标最靠近他的元素,两者比较,取最小值,并作为下一次寻道的当前位置。

设置了一个数组flag,用来标记磁道是否被访问过,下标与保存请求序列中的下标一一对应。

 

上代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5 #define min_num(x,y) (x<y?x:y)
 6 using namespace std;
 7 int main() {
 8     int a[100] = {0};//存放请求序列
 9     int sum = 0;//磁头移动总数
10     int i = 0;//i记录a数组的最后一个元素下标
11     do {
12         cin >> a[i];
13         i++;
14     } while (getchar() != '\n');
15     int start;//磁头起始位置
16     cin >> start;
17     a[i] = start;
18     int flag[100] = { 0 };//被访问过的标1
19     sort(a, a + i + 1);//递增排序
20     int j;
21     for (j = 0; j <= i ; j++) {
22         if (a[j] == start) {
23             flag[j] = 1;
24             break;
25         }
26     }
27     vector<int> v;
28     for (int k = 0; k < i; k++) {
29         //分别找左右边最近,并且没被访问过的
30         int left = j - 1;
31         int right = j + 1;
32         while (flag[left]&&left>=0) left--;
33         while (flag[right]&&right<=i) right++;
34         int min;
35         if (flag[left] == 1) {
36             min = a[right] - a[j];
37             j = right;
38         }
39         else if (flag[right] == 1) {
40             min = a[j] - a[left];
41             j = left;
42         }
43         else {
44             min = min_num(a[j] - a[left], a[right] - a[j]);
45             j = (a[j] - a[left] > a[right] - a[j] ? right : left);
46         }
47         flag[j] = 1;
48         v.push_back(a[j]);
49         sum += min;
50     }
51     vector<int>::iterator it;
52     for (it = v.begin(); it != v.end(); it++) {
53         cout << *it << " ";
54     }
55     cout << endl;
56     cout << sum;
57 
58     return 0;
59 }

 

 

posted @ 2019-11-24 20:19  lucky99  阅读(1023)  评论(0编辑  收藏  举报