题目
天空度假山庄里的物品实在是太多了,Madeline 想要帮 Oshiro 先生清理这些物品。
但物品对于未来而言都是可能有用的。
于是 Madeline 想出了一个方法,给每一个物品定义一个优先级,如果某个物品的最近使用过,那么它的优先级就更高。例如有两个物品,一个物品 A 在之前使用过,另一个物品 B 在物品 A 最后一次使用之后都没有使用过,那么物品 A 的优先级就比物品 B 的优先级高。
天空度假山庄的容量是有限的,只能存放  个物品,那么优先级前 
 大的物品就会被留下,而优先级比第 
 个物品优先级还要小的物品就会被扔掉。如果被扔掉的物品或者本来就没有的物品想要使用的话,就需要将物品购买回来使用。
一开始天空度假山庄中有  个物品,以及每一个物品的编号 
 和每一个物品的优先级的相对顺序。接下来的 
 天,每一天会使用一个编号为 
 的物品,你需要知道这一个物品是否需要购买。
解题思路
 表示编号为 
 的物品的优先级。如果值为 0,表示山庄中不存在该物品。
使用  将优先级与物品对应。数据结构 
 不仅可以根据优先级快速得出物品编号,还将物品按照优先级从小到大的顺序进行排列。
变量  记录物品之间的相对优先级。
给定一个物品编号 ,
- 如果 ,表示该物品存在于山庄,不需要购买,同时,将其优先级提高至目前最高。 
- 如果该物品不存在,则需要购买。
 如果山庄还没有满,则直接将该物品加入,并记录优先级(当前最高)。 
 如果山庄满了,将优先级最低的物品从中删除,将新物品加入,更新优先级。 
C++代码
#include<cstdio>
#include<map>
using namespace std;
const int maxn = 1e7+5;
long long level[maxn];
int main(){
    int n, m, q;
    scanf("%d%d%d", &n, &m, &q);
    map<long long, int> mp;
    int a;
    for(int i=1; i<=n; ++i){
        scanf("%d", &a);
        mp[i] = a;
        level[a] = i;
    }
    long long num = n+1;
    for(int i=0; i<q; ++i){
        scanf("%d", &a);
        if(level[a]){
            printf("no\n");
            mp.erase(level[a]);
        }
        else{
            printf("yes\n");
            if(mp.size()==m){
                auto it = mp.begin();
                level[it->second] = 0;
                mp.erase(it);
            }
        }
        level[a] = num;
        mp[num] = a;
        ++num;
    }
} 
 京公网安备 11010502036488号
京公网安备 11010502036488号