1 条题解

  • 3
    @ 2024-4-11 19:13:05

    内存的规则符合优先队列的特点,可以用一个优先队列,内部元素A包含tag idx cnt三个变量,分别表示时间戳(用于判断谁先进入内存)、页编号、访问次数。由于编号范围比较大,因此需要离散化。队列元素的优先级是:访问次数越少,优先级越高。访问次数相同时,时间戳越小,优先级越高。

    使用数组c记录每个页被访问的次数,如果当前页的c值大于0,说明成功命中。否则,如果内存还没有满,可以把当前页加入内存,并把页信息加入队列。如果内存已满,需要从优先队列里取出队首,如果队首的cnt和实际的c值不同,说明入队后它的访问次数增加了,此时需要用新的次数重新入队,然后继续取出新的队首,直到其cnt和实际c值相同为止。此时需要把队首出队,然后把新的页入队。

    在上述过程中统计命中的次数,即为答案。

    参考代码
    
    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN = 1e6 + 100;
    struct A {
        int tag, idx, cnt;
        bool operator < (const A& x) const {
            if (cnt == x.cnt)
                return tag > x.tag;
            return cnt > x.cnt;
        }
    };
    int n, m, p[MAXN], c[MAXN], sz, ans;
    priority_queue<A> que;
    vector<int> v;
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);cout.tie(0);
        cin >> n >> m;
        for (int i = 1; i <= m; i++) {
            cin >> p[i];
            v.push_back(p[i]);
        }
        sort(v.begin(), v.end());
        v.erase(unique(v.begin(), v.end()), v.end());
        for (int i = 1; i <= m; i++) {
            p[i] = lower_bound(v.begin(), v.end(), p[i]) - v.begin();
            if (c[p[i]] > 0) {
                c[p[i]]++;
                ans++;
            } else if (sz < n) {
                c[p[i]] = 1;
                que.push({i, p[i], 1});
                sz++;
            } else {
                while (que.top().cnt != c[que.top().idx]) {
                    A tp = que.top();
                    que.pop();
                    que.push({tp.tag, tp.idx, c[tp.idx]});
                }
                c[que.top().idx] = 0;
                que.pop();
                c[p[i]] = 1;
                que.push({i, p[i], 1});
            }
        }
        cout << ans;
        return 0;
    }
    
    • @ 2024-4-15 20:54:10

      老师你第13行少打了"< A >"

    • @ 2024-5-23 14:55:36

      @ 噢噢是的,代码已更新~

  • 1

信息

ID
713
时间
1000ms
内存
256MiB
难度
2
标签
(无)
递交数
30
已通过
22
上传者