zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",ans);
    54     }
    55     
    56     return 0;
    57 }

    -

  • 相关阅读:
    EasyUI datagrid动态生成列
    EasyUI easyui-combobox实现数据联动
    EasyUI中datagrid的基本用法
    Oracle update 执行更新操作后的数据恢复
    SqlHelper类
    oracle drop table(表)数据恢复方法
    C#微信公众号——本地调试
    git ignore 总结
    maya cmds pymel 选择 uv area(uv 面积) 为0 的面
    maya cmds pymel selectType() 选择类型切换
  • 原文地址:https://www.cnblogs.com/jiamian/p/13254255.html
Copyright © 2011-2022 走看看