其他分享
首页 > 其他分享> > Operating System(贪心、堆)

Operating System(贪心、堆)

作者:互联网

 

 

链接:https://ac.nowcoder.com/acm/problem/15688
来源:牛客网


时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

在学习Operating System的过程中,Glory遇到了这样一个问题,现在有一个大小为可以容纳N个页面的内存,硬盘内的内容被分成M个页面,用1~M来标识,一开始内存里没有任何页面,接下来用户会请求Q个页面,你需要设计一个置换算法,使得缺页发生的次数最少。缺页是指用户请求某个编号的页面,但这个页面没有在内存中的情况。发生缺页之后,你必须要把硬盘内对应的页面调入内存中,如果内存已满,你需要置换掉当前内存中的某个页面。

输入描述:

多组数据,请处理到输入结束。
每组数据,第一行为三个整数N,M,Q (0 < N,M,Q <= 50000)
接下来一行Q个数,表示用户请求的页面编号。

输出描述:

对于每组数据,输出一个数,表示最少的缺页次数。
示例1

输入

1 2 3 5
2 3 1 2 1 2
3 3 4 5 
4 3 2 1 4 3

输出

3
4

 

 

直接模拟OS最佳置换算法就行

 1 #include <bits/stdc++.h>
 2 typedef long long LL;
 3 #define pb push_back
 4 #define mst(a) memset(a,0,sizeof(a))
 5 const int INF = 0x3f3f3f3f;
 6 const double eps = 1e-8;
 7 const int mod = 1e9+7;
 8 const int maxn = 1e5+10;
 9 using namespace std;
10 
11 int a[maxn];
12 queue<int> qe[maxn];  //记录每个数所在位置下标
13 set<int> st;  //当前内存
14 
15 int main()
16 {
17     #ifdef DEBUG
18     freopen("sample.txt","r",stdin); //freopen("data.out", "w", stdout);
19     #endif
20     
21     int n,m,q;
22     while(~scanf("%d %d %d",&n,&m,&q))
23     {
24         st.clear();
25         for(int i=1;i<=q;i++)
26         {
27             scanf("%d",&a[i]);
28             qe[a[i]].push(i);
29         }
30         int ans = 0;
31         for(int i=1;i<=q;i++)
32         {
33             if(st.count(a[i])) qe[a[i]].pop();
34             else if(st.size()<n)
35             {
36                 st.insert(a[i]);
37                 qe[a[i]].pop();
38                 ans++;
39             }
40             else
41             {
42                 int pos = 0, t = 0;
43                 for(auto it : st)
44                 {
45                     if(qe[it].empty())
46                     {
47                         t = it;
48                         break;
49                     }
50                     if(qe[it].front()>pos)
51                     {
52                         pos = qe[it].front();
53                         t = it;
54                     }
55                 }
56                 st.erase(t);
57                 st.insert(a[i]);
58                 qe[a[i]].pop();
59                 ans++;
60             }
61         }
62         printf("%d\n",ans);
63     }
64     
65     return 0;
66 }

 

 

 

另一种用堆写的:

 1 #include <bits/stdc++.h>
 2 typedef long long LL;
 3 #define pb push_back
 4 #define mst(a) memset(a,0,sizeof(a))
 5 const int INF = 0x3f3f3f3f;
 6 const double eps = 1e-8;
 7 const int mod = 1e9+7;
 8 const int maxn = 1e5+10;
 9 using namespace std;
10 
11 int a[maxn];
12 int Next[maxn];  //Next[i]记录与当前a[i]相同值的下一个点所在的下标
13 int Last[maxn];  //Last[a[i]]记录与当前a[i]相同值的下一个点所在的下标
14 int vis[maxn];  //vis记录当前值是否在内存中
15 priority_queue<pair<int,int> > qe;  //first是Next,second是a[i]的值
16 
17 int main()
18 {
19     #ifdef DEBUG
20     freopen("sample.txt","r",stdin); //freopen("data.out", "w", stdout);
21     #endif
22     
23     int n,m,q;
24     while(~scanf("%d %d %d",&n,&m,&q))
25     {
26         memset(Last,INF,sizeof(Last));
27         memset(vis,0,sizeof(vis));
28         while(!qe.empty()) qe.pop();
29         for(int i=1;i<=q;i++)
30             scanf("%d",&a[i]);
31         for(int i=q;i>=1;i--)  //从后往前借助Last求出Next
32         {
33             Next[i] = Last[a[i]];
34             Last[a[i]] = i;
35         }
36         int num = 0;  //当前qe中有多少个不重复的a[i]
37         int ans = 0;
38         for(int i=1;i<=q;i++)
39         {
40             if(!vis[a[i]])
41             {
42                 if(num==n)  //当前装不下时,删除离它下一个一样的点的距离最远的点
43                 {
44                     vis[qe.top().second] = 0;
45                     qe.pop();
46                 }
47                 else num++;
48                 ans++;
49                 vis[a[i]] = 1;
50             }
51             qe.push({Next[i],a[i]});
52         }
53         printf("%d\n",ans);
54     }
55     
56     return 0;
57 }

 

 

 

 

 

 

 

-

标签:qe,const,int,System,Last,maxn,Operating,页面,贪心
来源: https://www.cnblogs.com/jiamian/p/13254255.html